我想证明一个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#。


当前回答

Go to the cryogenics lab in the New York City. Freeze yourself for (roughly) 1990 years. Get a job at Planet Express. Buy a brand-new CPU. Build a computer, run the program, and place it in the safe place with an pseudo-perpetual motion machine like the doomsday machine. Wait until the time machine is invented. Jump to the future using the time machine. If you bought 1YHz 128bit CPU, go to 3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps after when you started to run the program. ...? PROFIT!!!

... 即使你的1YHz CPU是1GHz CPU的1,000,000,000,000,000倍(如果你更喜欢使用二进制前缀,则为1,125,899,906,842,624倍),也至少需要10,783,127年。

因此,与其等着计算结束,不如去喂那些因为其他n只鸽子夺走了它们的家而失去家园的鸽子。:(

或者,你可以等到128位量子计算机被发明出来。然后,您可以通过在合理的时间内(可能)使用您的程序来证明GUID不是唯一的。

其他回答

假设你有理由相信生成guid的算法并不是生成真正的随机数,而是以周期<< 2^128为周期循环。

例如,RFC4122方法用于派生guid,该guid固定某些位的值。

循环的证明取决于周期的可能大小。

对于小周期,哈希表(GUID) -> GUID与碰撞替换 如果guid不匹配(如果匹配则终止)可能是一种方法。也可以考虑只在随机的一小部分时间内进行替换。

最终,如果两次碰撞之间的最大周期足够大(并且事先不知道),任何方法都只能产生一个概率,即如果碰撞存在的话,就会发现碰撞。

请注意,如果生成guid的方法是基于时钟的(参见RFC),那么可能无法确定是否存在冲突,因为(a)您无法等待足够长的时间让时钟转一圈,或者(b)您无法在一个时钟滴答内请求足够的guid来强制碰撞。

或者,您可以显示Guid中位之间的统计关系,或者Guid之间位的相关性。这样的关系可能使得算法很有可能是有缺陷的,而不一定能找到实际的碰撞。

当然,如果您只是想证明Guids可以碰撞,那么答案就是数学证明,而不是程序。

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

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

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

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

数到2^128,雄心勃勃。

让我们想象一下,每台机器每秒可以计算2^32个id——不是那么雄心勃勃,因为它甚至不到每秒43亿个。让我们用2^32台机器来完成这个任务。此外,让2^32个文明各自投入相同的资源来完成任务。

到目前为止,我们每秒可以计数2^96个id,这意味着我们将计数2^32秒(136年多一点)。

现在,我们所需要的是获得4294967296个文明,每个文明都有4294967296台机器,每台机器每秒能计算4294967296个id,在未来136年左右的时间里,纯粹是为了这项任务——我建议我们现在就开始这项基本任务;-)

我不明白为什么没人提到升级显卡…当然,如果你有一个高端的NVIDIA Quadro FX 4800或其他(192 CUDA核),这将会更快…

当然,如果你能买得起几台NVIDIA Qadro Plex 2200 s4(每台960 CUDA内核),这个计算真的会让人尖叫。也许NVIDIA愿意借给你一些作为“技术演示”的公关噱头?

他们当然想成为这场历史性算计的一部分……

如果生成的UUID的数量遵循摩尔定律,那么在可预见的未来永远用不完GUID的印象是错误的。

对于2^128个uuid,只需要18个月* Log2(2^128) ~= 192年,我们就会用完所有uuid。

而且我相信(虽然没有任何统计证据),自从UUID被大规模采用以来,在过去的几年里,我们生成UUID的速度比摩尔定律所规定的要快得多。换句话说,我们可能只有不到192年的时间来处理UUID危机,这比宇宙末日要快得多。

但由于我们肯定不会在2012年底之前将它们耗尽,我们将把这个问题留给其他物种来担心。