“简单证明GUID(全局唯一标识符)并不唯一”

GUID是什么,大家理所当然地应该都知道(百度百科介绍的GUID)。在.net framework中,微软为开发者提供了一个GUID结构,这个结构想必很多人在开发中应该已经用过,下面我们再来看一下它的备注说明:

“GUID 是一个 128 位整数(16 字节),可用于所有需要唯一标识符的计算机和网络。此标识符重复的可能性非常小。”

注意红色的标注,标识符是有重复的可能的,只不过重复的概率小之又小。到这里你我可能都会产生疑问,重复的可能性到底有多小呢?如何证明有重复呢?在stackoverflow上,一个善于思考勇于发现并提出问题挑战权威的C#开发先驱抛出了一个有趣的问答题:“Simple proof that GUID is not unique”(本文的标题就是按照英文原文标题直译过来的)。

在英文原文中,提问者说他想在一个测试程序中简单证明一下GUID并不唯一,然后给出了如下代码实现:

1
2
3
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());

令人感到遗憾的是,“it's not working”(实际上,拷贝这份代码到VS中,编译无法通过,BigInteger的构造函数根本不存在,for循环的地方写得也不对,估计是伪代码)。

接着,我们看到了投票次数最多的正确答案:

GuidCollisionDetector

楼猪第一次看到代码的时候,精神抖擞热情洋溢地分析如下:

1、定义一个字节数组reserveSomeRam,分配一块内存空间;

2、通过HashSet对象填充GUID,直至内存不足,通过GC的KeepAlive和Collect方法,释放出预留给reserveSomeRam的内存空间,保证程序有继续运行的微小内存空间(此时,楼猪惊呼,好一段惊世骇俗奇技淫巧的NB代码啊);

3、通过两个for循环,配合并行库,通过HashSet的Contains函数证明新产生的GUID有可能产生重复(这里主要就是CPU运算的事情了,完全用不到reserveSomeRam那一块的内存,充分地利用了CPU和内存,这种思想这种境界真是令人感到匪夷所思望尘莫及,牛)。

但是看到代码中的“throw new ApplicationException("Guids collided! Oh my gosh!");”和Console.WriteLine("Umm... why hasn't the universe ended yet?");,楼猪有一种穿越的感觉。

接着楼猪仔细看了一下这个正确答案的正文回答的细节,发现这家伙从头到尾都是一种煞有介事一本正经的口气,又是版权,又是要钱,又是坐着时光机回到2010年2月28号获得技术支持的…恍然大悟,kao,真是TM的太好玩太会扯淡了。

忍耐不住好奇,怀着强烈的求知欲望,楼猪看完了所有回答,有人用数学方法证明…祝你好运;有人寄希望于未来的量子计算机显灵;有人提议组织志愿者现在就开始他们伟大的136年证明之旅;有人提议升级显卡,NVIDIA 可能会贷款赞助这个历史性的计算;有人说他可以帮忙,已经被证明了,他曾经获得过某一个GUID数字……楼猪久违地又蛋疼了。

比较起来,个人感觉还是这个回答比较靠谱:

Well if the running time of 83 billion years does not scare you, think that you will also need to store the generated GUIDs somewhere to check if you have a duplicate; storing 2^128 16-byte numbers would only require you to allocate 4951760157141521099596496896 terabytes of RAM upfront, so imagining you have a computer which could fit all that and that you somehow find a place to buy terabyte DIMMs at 10 grams each, combined they will weigh more than 8 Earth masses, so you can seriously shift it off the current orbit, before you even press "Run". Think twice!

大致意思就是说,跑完证明程序,需要大概830亿年时间和4951760157141521099596496896 TB(1TB=1024GB)的内存空间(假设每个DIMM内存有10克重,所有的内存换算成重量,大概是8个地球的重量之和)。从看似有限而又无限的时间和空间上证明,GUID重复这种概率发生的可能性实在是太太太小了,可以认为基本不可能。有一个回复说,“Personally, I think the "Big Bang" was caused when two GUIDs collided.”,即:两个GUID重复之日,宇宙大爆炸之时。

实际上,楼猪现在也是这么认为的。
您有好的方法证明GUID会重复吗?







本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2011/05/02/2034403.html,如需转载请自行联系原作者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值