guide . newguid (). tobytearray()到字符串(数字)行是否仍然唯一

本文关键字:是否 唯一 字符串 newguid tobytearray guide 数字 | 更新日期: 2023-09-27 18:17:26

我需要生成一个由数字组成的唯一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); 

guide . newguid (). tobytearray()到字符串(数字)行是否仍然唯一

您需要在字节值之间使用分隔符或用零填充。否则就有交集。示例:3,5,6,7,123 => 003005006007123

是的,存在字节数组到Guids的1:1映射。在转换过程中没有信息丢失,因此您仍然保留与使用Guid的普通字符串表示相同的惟一性。

Guid实际上只是一个16字节的数字,无论您将其显示为{3F2504E0-4F89-41D3-9A0C-0305E82C3301}, 4AQlP4lP00GaDAMF6CwzAQ==还是224004037063137079211065154012003005232044051001,它都表示相同的数字。

EDIT:哎呀,正如mkysoft指出的,你必须处理前导零。将数字填充为3位可以解决这个问题

var guid = new Guid("{3F2504E0-4F89-41D3-9A0C-0305E82C3301}");
Console.WriteLine(string.Join(string.Empty, guid.ToByteArray().Select(x=>x.ToString("000"))));

UPDATE:实际上我只是想到了一个更好的解决方案,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

或者您可以使用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来拥有更大或更小的值集(取决于您希望标识符的大小)