假设 GUID 始终是唯一的是否安全?

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

附加问题

一个最佳的方法来测试 GUID 的唯一性? 布鲁姆过滤器?

54523 次浏览

虽然有可能发生碰撞,但几乎不可能。(数学 给你)可以有把握地认为它们实际上是不同的。

一般来说,是的,假设是安全的。

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

当然,这需要一个好的 GUID 生成器。因此,问题实际上在于您对用于生成 GUID 的工具的信任程度,以及它是否有自己的测试?

你可以的。由于 GUID 长度为128位,因此无可否认存在发生冲突的极小可能性ーー但“分钟”这个词远远不够强大。有 这么多的 GUID,如果你随机产生它们的 几万亿,你仍然更有可能被陨石撞击比有甚至一个碰撞(从 维基百科)。如果你不是随机生成它们,而是 例如:。使用 MAC 地址和时间戳算法,那么它们也将是唯一的,因为 MAC 地址在计算机中是唯一的,而时间戳在 你的计算机中也是唯一的。

编辑1: 为了回答你的额外问题,测试一组 GUID 的唯一性的最佳方法是假设它们都是唯一的。为什么?因为,考虑到你正在生成的 GUID 的数量,一个 GUID 碰撞的可能性比宇宙射线在你的计算机内存中翻转一点点并且搞砸任何你想运行的“准确”算法给出的答案的可能性要小。(数学见 这个 StackOverflow 的答案。)

引用道格拉斯 · 亚当斯的 银河系漫游指南:

“太空,”它说,“很大。真的很大。你不会相信它有多么巨大,令人难以置信。我的意思是,你可能认为这是一个漫长的道路下来的化学家,但这只是花生太空,听着...”

既然有 宇宙中大约有7 × 10 < sup > 22 颗恒星,而且还不到2128 GUID,那么每颗星大约有4.86 × 1015ーー几乎是 五千万亿ーー GUID。如果这些恒星中的每一颗都有一个像我们这样拥有繁荣人口的世界,那么在每一颗恒星周围,每一个曾经活过的人类或外星人将有资格获得超过四万五千个 GUID。对于历史上的每一个人对于宇宙中的每一颗恒星。GUID 空间的巨大程度与整个宇宙的大小相同。你做 没有需要担心。

(编辑2:反思: 哇。我没有意识到 我自己这意味着什么。GUID 空间大得难以置信。我有点敬畏它。)

对碰撞可能性的分析可以在维基百科上找到: http://en.wikipedia.org/wiki/Uuid#Random_UUID_probability_of_duplicates

正如在链接中提到的,这将受到随机数生成器的属性的影响。

GUID 生成器代码中还存在 bug 的可能性; 虽然这种可能性很低,但是根据数学计算,它们可能高于发生冲突的可能性。

Bloom 过滤器可能是合适的; 它可以快速告诉您 GUID 是否是唯一的,但是有可能出现错误的冲突指示。如果一次测试一个批处理,另一种方法是对批处理进行排序并比较每个连续的元素。

简短的回答: 出于实际目的,是的。

但是,你必须考虑生日问题!

我计算了一些典型的碰撞概率。对于 维基百科的文章中指定的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 将被用于相同目的的可能性非常小,因此在实践中不存在任何问题。

这个主题让我想起了扑克牌场景。也就是说,一副52张牌可以有很多种排列方式,因此可以肯定的是,从来没有哪两副洗得很好的牌是按同样的顺序排列的。

如果你现在拿起一副牌,把它洗牌,那么这个序列将是独一无二的,而且可能永远不会再出现在全人类中。事实上,排列任何事物的52种方法的潜在数量是如此之大,以至于任何2副牌发生相同顺序的可能性几乎为零。

在这个例子中,有40个被洗牌的甲板,想要确定它们都是独一无二的,这不是不可能的,其中两个是相同的,但是如果你能够每十分之一秒洗一次所有的甲板,并且你从宇宙的诞生开始,这种情况很可能不会发生。