我想证明一个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#。
假设你有理由相信生成guid的算法并不是生成真正的随机数,而是以周期<< 2^128为周期循环。
例如,RFC4122方法用于派生guid,该guid固定某些位的值。
循环的证明取决于周期的可能大小。
对于小周期,哈希表(GUID) -> GUID与碰撞替换
如果guid不匹配(如果匹配则终止)可能是一种方法。也可以考虑只在随机的一小部分时间内进行替换。
最终,如果两次碰撞之间的最大周期足够大(并且事先不知道),任何方法都只能产生一个概率,即如果碰撞存在的话,就会发现碰撞。
请注意,如果生成guid的方法是基于时钟的(参见RFC),那么可能无法确定是否存在冲突,因为(a)您无法等待足够长的时间让时钟转一圈,或者(b)您无法在一个时钟滴答内请求足够的guid来强制碰撞。
或者,您可以显示Guid中位之间的统计关系,或者Guid之间位的相关性。这样的关系可能使得算法很有可能是有缺陷的,而不一定能找到实际的碰撞。
当然,如果您只是想证明Guids可以碰撞,那么答案就是数学证明,而不是程序。
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不是唯一的。