我想证明一个GUID在一个简单的测试程序中不是唯一的。 我原以为下面的代码会运行几个小时,但它不起作用。我该怎么做呢?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

我用的是c#。


当前回答

对我来说. .单个核心生成UUIDv1所需的时间保证了它是唯一的。即使在多核情况下,如果UUID生成器一次只允许为特定资源生成一个UUID(请记住,多个资源可以完全利用相同的UUID,但不太可能,因为资源本身就是地址的一部分),那么您将拥有足够多的UUID,直到时间戳耗尽为止。在这一点上,我真的怀疑你会在乎。

其他回答

你可以用量子bogosort算法的变体在O(1)时间内证明这一点。

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

当然guid也会发生碰撞。由于guid是128位的,只需生成其中的2^128 + 1个,根据鸽子洞原理,肯定会有碰撞。

但是当我们说一个GUID是唯一的时,我们真正的意思是键空间非常大,实际上不可能意外地生成两次相同的GUID(假设我们是随机生成GUID)。

如果随机生成n个guid序列,那么至少发生一次碰撞的概率大约是p(n) = 1 - exp(-n^2 / 2 * 2^128)(这是一个生日问题,可能的生日数量为2^128)。

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

为了使这些数字具体化,2^60 = 1.15e+18。所以,如果你每秒生成10亿个guid,你将需要36年才能生成2^60个随机guid,即使这样,你发生碰撞的概率仍然是1.95e-03。在接下来的36年里,你更有可能在生命中的某个时刻被谋杀(4.76e-03),而不是发现一次碰撞。祝你好运。

guid是124位,因为4位保存版本号。

任何两个guid都很可能是唯一的(不相等)。

看看这个SO条目,来自维基百科

而每个生成的GUID不是 保证是唯一的,总数 唯一键数(2^128或 3.4×10^38)是如此之大,以至于相同数字的概率为 生成两次是非常小的。为 例子,考虑可观测 宇宙,其中包含约5×10^22 星星;每颗恒星都有可能 6.8×10^15个通用唯一的guid。

所以你可能还要再等几十亿年,希望在我们所知道的宇宙结束之前,你能击中一个。

GUID理论上是非唯一的。下面是你的证明:

GUID是一个128位的数字 如果不重用旧的guid,就不能生成2^128 + 1或更多的guid

然而,如果太阳的全部能量输出都用于完成这一任务,那么它在完成之前就会变冷。

GUID可以使用许多不同的策略生成,其中一些策略采取特殊措施来确保给定的机器不会两次生成相同的GUID。在特定算法中发现冲突将表明生成guid的特定方法不好,但不能证明关于guid的任何一般情况。