C# 字符串(数字)行的Guid.NewGuid().ToByteArray()是否仍然唯一

C# 字符串(数字)行的Guid.NewGuid().ToByteArray()是否仍然唯一,c#,guid,C#,Guid,我需要生成一个由数字组成的唯一id 以下结果字符串uniqueId是否与guid.ToString()的结果一样唯一 是的,字节数组与GUID之间有1:1的映射。转换过程中不会丢失任何信息,因此您仍然保留与使用Guid的正常字符串表示形式相同的唯一性 Guid实际上只是一个16字节的数字,如果将其显示为{3F2504E0-4F89-41D3-9A0C-0305E82C3301},4AQlP4lP00GaDAMF6CwzAQ=或22400403706370137079211065154012005

我需要生成一个由数字组成的唯一id

以下结果字符串
uniqueId
是否与
guid.ToString()
的结果一样唯一


是的,字节数组与GUID之间有1:1的映射。转换过程中不会丢失任何信息,因此您仍然保留与使用Guid的正常字符串表示形式相同的唯一性

Guid实际上只是一个16字节的数字,如果将其显示为
{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
4AQlP4lP00GaDAMF6CwzAQ=
22400403706370137079211065154012005232044051001,则表示相同的数字

编辑:Oops,您必须处理前导零。将数字填充到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}
变成
4743222283439768800000862192878292122

是的,字节数组到guid的映射是1:1。转换过程中不会丢失任何信息,因此您仍然保留与使用Guid的正常字符串表示形式相同的唯一性

Guid实际上只是一个16字节的数字,如果将其显示为
{3F2504E0-4F89-41D3-9A0C-0305E82C3301}
4AQlP4lP00GaDAMF6CwzAQ=
22400403706370137079211065154012005232044051001,则表示相同的数字

编辑:Oops,您必须处理前导零。将数字填充到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}
变为
4743222283439768800000862192878292122

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

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

或者您可以使用biginger.ToString()来处理将大数字转换为字符串的问题(因为它在这方面非常擅长)


仅当您需要正数时才调整大小(否则,您获得负数的几率为50%)。您还可以使用
System.Security.Cryptography.RandomNumberGenerator.GetBytes
来获得更大或更小的值集(取决于您希望标识符的大小)

或者您可以使用biginger.ToString()来处理将大数字转换为字符串的问题(因为它非常擅长于此)


仅当您需要正数时才调整大小(否则,您获得负数的几率为50%)。您还可以使用
System.Security.Cryptography.RandomNumberGenerator.GetBytes
来设置更大或更小的值集(取决于您希望标识符的大小)

+1,或者您可以确保每个字节由三个字符表示。(前导零作为填充)+1,或者您可以确保每个字节由三个字符表示。(以前导零作为填充)正如@myyosft所指出的,有没有前导零的交点?在哪种情况下会发生这种情况?三位数字如何解决问题(例如4位数字)?@Odrai一个字节的最大值是255,因此000001,…,254255。十六进制更紧凑,00,01,…,FE,FF。@Odrai如果我给你数字
425
是源代码
4,25
还是
42,5
?通过添加前导零,使其成为
004025
,现在在选择哪一个之间没有歧义。一个字节可以代表0到255之间的任何数字,我们使用3位数,因为一个字节可以代表的最大数字是3位数。@Odrai请参阅我的最新更新。我想出了一个更好的解决方案,最终得到的数字会更短。与我们处理单个
字节
对象的原理相同,但它使用2
Uint64
s而不是16
字节
s。我还意识到,在第一个字节/UInt64上不需要前导0,所以这就是节省大量空间的原因。正如@myyosft所指出的,有没有前导零的交集?在哪种情况下会发生这种情况?三位数字如何解决问题(例如4位数字)?@Odrai一个字节的最大值是255,因此000001,…,254255。十六进制更紧凑,00,01,…,FE,FF。@Odrai如果我给你数字
425
是源代码
4,25
还是
42,5
?通过添加前导零,使其成为
004025
,现在在选择哪一个之间没有歧义。一个字节可以代表0到255之间的任何数字,我们使用3位数,因为一个字节可以代表的最大数字是3位数。@Odrai请参阅我的最新更新。我想出了一个更好的解决方案,最终得到的数字会更短。与我们处理单个
字节
对象的原理相同,但它使用2
Uint64
s而不是16
字节
s。此外,我还意识到您不需要在第一个字节/UInt64上使用前导0,因此这就是节省大量空间的原因。关于
BigIntiger
的好主意!完全忘记了。这比我上次的更新还要好。关于
BigIntiger
的好主意!完全忘记了。这比我上次的更新还要好。