博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
“简单证明GUID(全局唯一标识符)并不唯一”
阅读量:6225 次
发布时间:2019-06-21

本文共 4219 字,大约阅读时间需要 14 分钟。

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

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

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

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

BigInteger begin = new BigInteger((long)0);            BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128            for(begin; begin

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

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

GuidCollisionDetectorusing System;using System.Collections.Generic;using System.Linq;namespace GuidCollisionDetector{    class Program    {        static void Main(string[] args)        {            var reserveSomeRam = new byte[1024 * 1024 * 100];            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);            // Fill up memory with guids.               var bigHeapOGuids = new HashSet
(); try { do { bigHeapOGuids.Add(Guid.NewGuid()); } while (true); } catch (OutOfMemoryException) { // Release the ram we allocated up front. GC.KeepAlive(reserveSomeRam); GC.Collect(); } Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount()); // Spool up some threads to keep checking if there's a match. // Keep running until the heat death of the universe. for (long k = 0; k < Int64.MaxValue; k++) { for (long j = 0; j < Int64.MaxValue; j++) { Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount); System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) => { if (bigHeapOGuids.Contains(Guid.NewGuid())) throw new ApplicationException("Guids collided! Oh my gosh!"); }); Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount); } } Console.WriteLine("Umm... why hasn't the universe ended yet?"); } }}

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

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会重复吗?

转载地址:http://hvuna.baihongyu.com/

你可能感兴趣的文章
用fail2ban防止黑客暴力破解服务器密码
查看>>
windows开机后键盘失灵(非硬件原因)解决办法
查看>>
程序员简易成长指南:从菜鸟码农到架构师
查看>>
Linux 技巧:让进程在后台可靠运行的几种方法
查看>>
cloudstack centOS安装(二)
查看>>
grep -- 一个正则表达式的执行者
查看>>
Weblogic 布署
查看>>
VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结...
查看>>
IOS多线程-1
查看>>
javascript:直播吧
查看>>
【虚拟化-基础篇】安装部署ESXi
查看>>
基于SDN,NFV的服务感知网络架构下篇
查看>>
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
查看>>
VMware Agent 安装完成后,RDP无法连接
查看>>
apache+多版本php
查看>>
关于测试人员的职业发展
查看>>
C++与C#数据类型比较总结
查看>>
Try .NET & Github Gist
查看>>
Windows页目录自映射方案
查看>>
java 线程之executors线程池
查看>>