GUID是否总是唯一的,可以这样假设吗?

137

我知道冲突的可能性很小,但如果我生成了一批1000个GUID(例如),可以安全地假设它们都是唯一的,以节省测试每一个的时间吗?

奖励问题

测试GUID唯一性的最佳方式是什么?也许是布隆过滤器?


38
如果我们都不停地刷新这个网站:http://www.wasteaguid.info/,那就不行了。 - mipadi
14
我把我所有的漏洞都归咎于全局唯一标识符(GUID)的冲突。这种情况迟早会发生,对吧? - Michael
11
更有可能的是一只身上有华丽格子花纹的鲨鱼从天而降摧毁你的电脑,因此我建议在你整体风险减少计划中采取预防措施更为恰当。请分配好资源。 - David Gladfelter
4
@mipadi:太好了,链接棒极了!我能想象到某个开发者会抱怨:“大家别再浪费 GUID 了!我需要它们!” - FrustratedWithFormsDesigner
2
Guid浪费应该有一个"剩余guids"计数器 @mipadi - Andy
显示剩余3条评论
7个回答

377
是的,你可以。由于GUID长度为128位,虽然有可能会发生冲突,但“可能性”一词远远不够强烈。有如此之多的GUID,如果您随机生成数万亿个GUID,仍然更有可能被流星击中,而不是发生冲突(来自Wikipedia)。如果您不是随机生成它们,而是使用MAC地址和时间戳算法,那么它们也将是唯一的,因为MAC地址在计算机中是唯一的,时间戳在您的计算机上是唯一的。 编辑1:回答您的奖励问题,测试一组GUID的唯一性的最佳方法是假设它们都是唯一的。为什么?鉴于您正在生成的GUID数量,GUID冲突的几率比宇宙射线翻转计算机内存中的一个位并搞乱任何“准确”算法给出的答案的几率要小。 (有关详细信息,请参见this StackOverflow answer的数学原理。)
有大量的GUID存在。引用道格拉斯·亚当斯的《银河系漫游指南》:
“太空,”它说,“很大。真的很大。你简直无法想象它有多么巨大,这让人难以置信。我的意思是,你可能认为去药房的路很长,但那只是小事,听着……”由于宇宙中有约7×1022颗星星,而GUIDs仅有2128个,因此每颗恒星大约有4.86×1015——几乎是五千万亿——个GUIDs。如果每颗恒星上都有像我们一样繁荣的人口世界,那么每颗恒星周围,每一个曾经存在的人类或外星人都有超过四万五千个GUIDs。对于宇宙中每颗恒星上的每个人来说,GUID空间与整个宇宙的大小相同。你不需要担心。(编辑2:反思这一点:哇。我自己都没有意识到这意味着什么。GUID空间是难以理解的巨大。我有点敬畏它。)”

2
此外,WolframAlpha报告称,对于每个曾经存在的人体内的每个细胞,都有36万亿个UUID。你的身体大约有10^14个细胞,共有1065亿人曾经生活过。或者说,美国公共债务每一分钱都有2.385 * 10^23个UUID。 - new123456
5
尽管数量仍然很高,但在 2^64 个GUID中,发生GUID冲突的概率已经超过了50%。 - NullUserException
1
在2^64个GUID中,这将把数字减少到每颗星球不到一个(0.00026),对于每个曾经存在的人类或外星人来说,只有2*10^(-15)。这仍然允许每个曾经存在的人类拥有超过1.7亿个GUID,所以我认为我们还是很好的。 - NullUserException
15
值得注意的是,仅当GUID在相同的业务空间中时,GUID冲突才是一个问题。我用来标识软件组件的GUID可能与你在自己应用程序中数据库行中使用的GUID相同,而不会导致任何问题。 - James Thorpe
2
有2^128个GUIDS这一事实是无关紧要的,而且在50%的碰撞几率下你甚至不算“还可以”,在0.0000001%的几率下你也不算好。 - BlackTigerX
显示剩余2条评论

46

简短回答:实际上是的。

然而,你必须考虑生日悖论!

我计算了一些代表性的碰撞概率。根据维基百科文章中指定的122位UUID,如果你生成至少2.71492e18个UUID,则碰撞的概率为1/2。生成10^19个UUID,概率为0.999918。生成10^17个UUID,概率为0.000939953。

维基百科上可以找到一些比较的数字。因此,你可以为每一个已经出生的人、观测宇宙中的每个星系、海洋中的每条鱼和地球上每只蚂蚁分配一个UUID。但是,如果你为每年人类生产的每个晶体管、地球上的每只昆虫、每粒沙子、观测宇宙中的每颗恒星或任何更大的东西生成一个UUID,则几乎肯定会发生碰撞。

如果你每秒生成10亿个UUID,则需要大约36年时间才能使碰撞概率达到10%。

最终,生成的UUID集合中很可能会发生碰撞。然而,碰撞的UUID用于相同的目的的概率非常小,在实践中没有问题。


25
宇宙的终结方式是这样的......某些程序员假定他们的全局唯一标识符对于他们的超级死星永远都是唯一的。 - pkr
因为UUID基于非随机数据,所以36年内你只需要关注每个毫秒。 - mjaggard
@mjaggard UUIDs基于随机数据。无论现代排序如何。 - Hakanai

8
在维基百科上可以找到有关碰撞可能性的分析:http://en.wikipedia.org/wiki/Uuid#Random_UUID_probability_of_duplicates。如链接中所述,这将受随机数生成器属性的影响。
GUID生成器代码中也可能存在错误的可能性;虽然概率较低,但它们可能比基于数学的碰撞概率要高。
布隆过滤器可能是合适的选择;它可以快速告诉您GUID是否唯一,但是存在误指示碰撞的可能性。如果您一次测试一批,则可以对批进行排序并比较每个连续元素作为替代方法。

5

一般而言,可以假设是安全的。

如果您的GUID生成器真正是随机的,那么在1000个GUID中发生冲突的可能性非常小。

当然,这需要一个好的GUID生成器。所以问题实际上是关于您信任使用的生成GUID工具有多少,并且它是否有自己的测试?


1
这个话题让我想起了卡牌的情景。也就是说,52张牌有很多种排列方式,因此可以肯定,没有两副正确洗牌过的牌组曾经处于相同的顺序。
如果你现在拿一副牌并将其洗牌,那么这个顺序将是独一无二的,并且很可能永远不会在人类历史上再次出现。事实上,任何52个物品排列的潜在方式都是难以想象的巨大,使得任何两副牌恰好处于相同顺序的机会接近于零。
在这个例子中,有40副已经被洗牌的牌组,想要确定它们都是唯一的,虽然有可能其中两副是相同的,但如果你能每十分之一秒洗一次所有的牌组,并从宇宙诞生开始,那么这种情况很可能不会发生。

0

虽然碰撞是可能的,但极不可能发生。(数学在这里。)可以安全地假设它们实际上是不同的。



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接