Guid.NewGuid().ToByteArray() 到字符串(数字)行是否仍然唯一
Is Guid.NewGuid().ToByteArray() to a string (number) line still unique
我需要生成一个由数字组成的唯一 ID。
下面的结果字符串 uniqueId
是否与 guid.ToString()
的结果一样唯一?
Guid guid = Guid.NewGuid();
byte[] guidBytes = guid.ToByteArray();
// Is the result (uniqueId) as unique as guid.ToString()?
string uniqueId = string.Join(string.Empty, guidBytes);
是的,存在字节数组到 Guid 的 1:1 映射。转换过程中不会丢失任何信息,因此您仍然保留与使用 Guid 的普通字符串表示相同的唯一性。
一个Guid其实就是一个16字节的数字,不管你是{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
、4AQlP4lP00GaDAMF6CwzAQ==
还是224004037063137079211065154012003005232044051001
,都代表同一个数字.
编辑: 糟糕,,您必须处理前导零。将数字填充为 3 位数字即可解决问题
var guid = new Guid("{3F2504E0-4F89-41D3-9A0C-0305E82C3301}");
Console.WriteLine(string.Join(string.Empty, guid.ToByteArray().Select(x=>x.ToString("000"))));
更新: 其实我只是想到了一个更好的解决方案,Guid 是一个 128 位数字,通过使用 2 个 64 位数字并在数字上填充数字的 0第二部分你会得到一个更短但仍然独特的数字。
var guid = new Guid("{3F2504E0-4F89-41D3-9A0C-0305E82C3301}");
var guidBytes = guid.ToByteArray();
Console.WriteLine("{0}{1}", BitConverter.ToUInt64(guidBytes, 0), BitConverter.ToUInt64(guidBytes,8).ToString().PadLeft(20, '0'));
这将输出一个长度在 21 到 40 位之间的唯一整数,{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
变为 474322228343976880000086462192878292122
,
您需要在字节值之间使用分隔符或用零填充。否则有交集。
示例:3,5,6,7,123 => 003005006007123
或者您可以使用 BigInteger.ToString() 来处理将大数字转换为字符串(因为它真的很擅长)
var p = Guid.NewGuid().ToByteArray();
Array.Resize(ref p, p.Length + 1);
Console.WriteLine(new BigInteger(p));
仅当您需要正数时才调整大小(否则您有 50% 的机会得到负数)。您还可以使用 System.Security.Cryptography.RandomNumberGenerator.GetBytes
来获得更大或更小的一组值(取决于您希望标识符的大小)
我需要生成一个由数字组成的唯一 ID。
下面的结果字符串 uniqueId
是否与 guid.ToString()
的结果一样唯一?
Guid guid = Guid.NewGuid();
byte[] guidBytes = guid.ToByteArray();
// Is the result (uniqueId) as unique as guid.ToString()?
string uniqueId = string.Join(string.Empty, guidBytes);
是的,存在字节数组到 Guid 的 1:1 映射。转换过程中不会丢失任何信息,因此您仍然保留与使用 Guid 的普通字符串表示相同的唯一性。
一个Guid其实就是一个16字节的数字,不管你是{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
、4AQlP4lP00GaDAMF6CwzAQ==
还是224004037063137079211065154012003005232044051001
,都代表同一个数字.
编辑: 糟糕,
var guid = new Guid("{3F2504E0-4F89-41D3-9A0C-0305E82C3301}");
Console.WriteLine(string.Join(string.Empty, guid.ToByteArray().Select(x=>x.ToString("000"))));
更新: 其实我只是想到了一个更好的解决方案,Guid 是一个 128 位数字,通过使用 2 个 64 位数字并在数字上填充数字的 0第二部分你会得到一个更短但仍然独特的数字。
var guid = new Guid("{3F2504E0-4F89-41D3-9A0C-0305E82C3301}");
var guidBytes = guid.ToByteArray();
Console.WriteLine("{0}{1}", BitConverter.ToUInt64(guidBytes, 0), BitConverter.ToUInt64(guidBytes,8).ToString().PadLeft(20, '0'));
这将输出一个长度在 21 到 40 位之间的唯一整数,{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
变为 474322228343976880000086462192878292122
,
您需要在字节值之间使用分隔符或用零填充。否则有交集。 示例:3,5,6,7,123 => 003005006007123
或者您可以使用 BigInteger.ToString() 来处理将大数字转换为字符串(因为它真的很擅长)
var p = Guid.NewGuid().ToByteArray();
Array.Resize(ref p, p.Length + 1);
Console.WriteLine(new BigInteger(p));
仅当您需要正数时才调整大小(否则您有 50% 的机会得到负数)。您还可以使用 System.Security.Cryptography.RandomNumberGenerator.GetBytes
来获得更大或更小的一组值(取决于您希望标识符的大小)