如何生成绝对独特的GUID?

Age*_*ire 6 c#

有没有办法在每次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...
  • 如注释中所述,这将产生无效UUID的值

当然,这绝不是随机的......

在实践中,正如其他人所提到的,碰撞的可能性Guid.NewGuid非常小.

  • @Sangram:我不确定你要做的是什么.碰撞的可能性很小,但使用正常方法非零.我的代码生成了所有可能的GUID,没有任何重复. (2认同)

Cod*_*aos 6

不是100%.但是如果您的GUID生成器运行良好,则碰撞概率非常小.这实际上可以算作0.

随机生成的(种类4)guid具有大约120个随机位.从生日问题中你可以看到,一旦你产生大约2 ^ 60或10 ^ 18个GUID,碰撞很可能会发生,这是一个很大的问题.

所以简单地使用Guid.NewGuid()应该足够好.


您提出的解决方案不是一个好主意IMO:

  • 如果你有很多GUID,它可能会占用大量内存
  • 由于您需要在本地知道所有GUID,因此没有理由首先使用GUID.一个简单的整数计数器也可以完成这项工作.
  • 随机GUID冲突不如故障硬件破坏您的数据结构.

您的代码本身对我来说是正确的.即如果您注册所有GUID并且您的硬件完美运行,并且软件没有其他错误,则保证不会发生冲突.

当然它也不是线程安全的,这对于静态方法来说是出乎意料的.