有没有办法在每次100%新GUID时生成而没有任何机会在整个应用程序中发生冲突?
由于我无法在八小时内回答我的问题,我想出了解决方案:
internal static class GuidGenerator
{
private static readonly HashSet<Guid> _guids = new HashSet<Guid>();
internal static Guid GetOne()
{
Guid result;
lock (_guids)
while (!_guids.Add(result = Guid.NewGuid())) ;
return result;
}
internal static void Utilize(Guid guid)
{
lock (_guids)
_guids.Remove(guid);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码是否解决了应用程序中的问题?
编辑:呃,它变得复杂了.线程安全性会降低速度.
Mar*_*ade 22
不,没有任何方法可以生成绝对唯一的 GUID.只有3.40282367×10 38个可能的GUID,因此星系会发生碰撞,所以这些标识符也会发生冲突.即使对于单个应用程序,它也取决于应用程序具有多少GUID.除非您的应用程序大于Google的所有索引器,否则您不需要为此而失眠.只是用Guid.NewGuid().
Jon*_*eet 16
当然.GUID只是一个128位的值.因此,使用128位整数(例如,由两个ulong值表示)并递增它.当您达到128位整数类型的最大值时,您已生成所有可能的GUID.例如:
public IEnumerable<Guid> GetAllGuids()
{
unchecked
{
byte[] buffer = new byte[16];
ulong x = 0UL;
do
{
byte[] high = BitConverter.GetBytes(x);
Array.Copy(high, 0, buffer, 0, 8);
ulong y = 0UL;
do
{
y++;
byte[] low = BitConverter.GetBytes(y);
Array.Copy(low, 0, buffer, 8, 8);
yield return new Guid(buffer);
} while (y != 0UL);
x++;
} while (x != 0UL);
}
}
Run Code Online (Sandbox Code Playgroud)
笔记:
ulong值是一种痛苦 - 我不喜欢使用do...while...当然,这绝不是随机的......
在实践中,正如其他人所提到的,碰撞的可能性Guid.NewGuid非常小.
不是100%.但是如果您的GUID生成器运行良好,则碰撞概率非常小.这实际上可以算作0.
随机生成的(种类4)guid具有大约120个随机位.从生日问题中你可以看到,一旦你产生大约2 ^ 60或10 ^ 18个GUID,碰撞很可能会发生,这是一个很大的问题.
所以简单地使用Guid.NewGuid()应该足够好.
您提出的解决方案不是一个好主意IMO:
您的代码本身对我来说是正确的.即如果您注册所有GUID并且您的硬件完美运行,并且软件没有其他错误,则保证不会发生冲突.
当然它也不是线程安全的,这对于静态方法来说是出乎意料的.