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

Posted

技术标签:

【中文标题】假设 GUID 始终是唯一的是不是安全?【英文标题】:Is it safe to assume a GUID will always be unique?假设 GUID 始终是唯一的是否安全? 【发布时间】:2011-02-27 23:42:12 【问题描述】:

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

额外问题

测试 GUID 唯一性的最佳方法?布隆过滤器可能吗?

【问题讨论】:

Is a GUID unique 100% of the time? 的可能重复项 如果我们一直在这个网站上捣碎重新加载按钮,那就不行了:wasteaguid.info 我将所有错误都归咎于 GUID 冲突。它必须发生一段时间吧? 一条有着可爱格子图案颜色的鲨鱼更有可能从天而降,把你的电脑砸得粉碎,所以我认为采取预防措施是更合适的资源分配作为整体风险降低计划的一部分。 @mipadi:很棒的链接!我可以想象某个开发人员在某处抱怨“Guuuuys!停止浪费 GUID!我需要那些!” 【参考方案1】:

是的,你可以。由于 GUID 的长度为 128 位,诚然存在冲突的微小可能性——但“分钟”这个词还远远不够强大。有如此多的 GUID,如果你随机生成 几万亿 个 GUID,你仍然更有可能被陨石击中而不是发生一次碰撞(来自 @ 987654321@)。如果您不是随机生成它们,而是例如使用 MAC 地址和时间戳算法,那么它们也将是唯一的,因为 MAC 地址在计算机中是唯一的您的计算机上的时间戳是唯一的。

编辑 1:要回答您的额外问题,测试一组 GUID 的唯一性的最佳方法是假设它们都是唯一的。为什么?因为,鉴于您正在生成的 GUID 的数量,GUID 碰撞的几率小于宇宙射线在您的计算机内存中翻转一点并搞砸您所关心的任何“准确”算法给出的答案的几率跑步。 (有关数学,请参阅 this *** answer。)

那里有 大量 数量的 GUID。引用道格拉斯·亚当斯 (Douglas Adams) 的银河系漫游指南

“空间,”它说,“很大。真的很大。你简直不会相信它有多么大得令人难以置信。我的意思是你可能认为通往化学家的道路还有很长的路要走,但这只是花生到太空,听……”

由于有 about 7×1022 stars in the universe,并且不到 2128 个 GUID,因此大约有 4.86×1015 - 几乎 5 万亿—每颗星的 GUID。如果这些恒星中的每一颗都拥有像我们这样人口众多的世界,那么在每一颗恒星周围,every human or alien who had ever lived 将有权获得超过四万五千个 GUID。对于宇宙中每颗恒星的历史上的每一个人。 GUID 空间与整个宇宙的大小处于同一水平。你确实不需要担心。

编辑 2: 回想一下:哇。我自己还没有意识到 我自己这是什么意思。GUID 空间大得难以理解。我有点敬畏它。)

【讨论】:

此外,WolframAlpha 报告说,对于每个曾经生活过的人的每个细胞,都有 36 万亿个 UUID。你的身体里有大约10^14 个细胞,曾经有 1065 亿人生活过。或者,2.385 * 10^23 UUID 对应美国公共债务中的每一分钱。 虽然数字仍然很高,但在 2^64 个 GUID 处发生 GUID 冲突的可能性超过 50%。 在 2^64 GUID 时,这会将宇宙中每颗恒星的数字减少到不到一 (0.00026),而对于每个曾经生活过的人类或外星人来说,数字会减少到 2*10^(-15) .这仍然允许为每个曾经生活过的人类提供超过 1.7 亿个 GUID,所以我认为我们仍然很好。 值得注意的是,GUID 冲突也只有在同一个业务空间中才会出现问题。我用来识别软件中的组件的 GUID 可能与您在自己的应用程序的数据库行中使用的 GUID 相同,而不会导致任何问题 有 2^128 个 GUIDS 的事实是无关紧要的,你在 50% 的碰撞几率上“仍然不擅长”,你甚至不擅长 0.0000001%【参考方案2】:

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

但是,您必须考虑生日悖论!

我计算了几个有代表性的碰撞概率。对于 the Wikipedia article 中指定的 122 位 UUID,如果您至少生成 2.71492e18 UUID,则冲突概率为 1/2。使用 10^19 个 UUID,概率为 0.999918。使用 10^17 个 UUID,0.000939953。

Some numbers for comparison can be found on Wikipedia. 因此,您可以安全地为每个活过的人类、可观测宇宙中的每个星系、海洋中的每条鱼以及地球上的每只蚂蚁分配一个 UUID。 然而,如果你为人类一年生产的每个晶体管、地球上的每只昆虫、地球上的每一粒沙子、可观测宇宙中的每颗恒星或任何更大的东西生成一个 UUID,碰撞几乎是肯定的。

如果您每秒生成 10 亿个 UUID,it would take about 36 years 将获得 10% 的碰撞概率。

最终,在人类历史进程中生成的一组 UUID 之间可能会发生冲突。尽管如此,碰撞的 UUID 被用于相同目的的可能性仍然很小,因此在实践中没有问题。

【讨论】:

这就是宇宙的终结方式......一些程序员只是假设他们的 GUID 对于他们的巨型死星来说总是独一无二的...... 因为 UUID 是基于非随机数据的,所以 36 年是 - 您只需要单独担心每一毫秒。 @mjaggard UUID 基于随机数据。无论如何,任何现代类型。【参考方案3】:

关于碰撞可能性的分析可以在***上找到:http://en.wikipedia.org/wiki/Uuid#Random_UUID_probability_of_duplicates

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

GUID 生成器代码中也可能存在错误;虽然几率很低,但根据数学计算,它们可能比发生碰撞的几率要高。

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

虽然可能发生碰撞,但可能性极小。 (数学here。)可以肯定地假设它们实际上是不同的。

【讨论】:

【参考方案6】:

通常这是一个非常安全的假设。

http://en.wikipedia.org/wiki/Globally_Unique_Identifier

Is a GUID unique 100% of the time?

【讨论】:

【参考方案7】:

这个话题让我想起了纸牌场景。也就是说,一副 52 张牌的排列方式有很多种,几乎可以肯定,从来没有 2 张经过正确洗牌的牌组的顺序是相同的。

如果你现在拿一副套牌洗牌,那么这个顺序将是独一无二的,并且可能永远不会再出现在全人类中。事实上,安排 52 种任何东西的潜在方法数量之多令人难以想象,以至于任何 2 个套牌碰巧是相同顺序的可能性几乎为零。

在这个有 40 个洗牌的套牌并想确定它们都是独一无二的例子中,其中 2 个是相同的并非不可能,但如果你能够将所有套牌洗牌一次,这很可能不会发生每隔十分之一秒,你就开始了宇宙的诞生。

【讨论】:

以上是关于假设 GUID 始终是唯一的是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章

假设路径C: WINDOWS system32始终存在是否安全?

Active Director用户GUID

始终将 DBNull SqlParameter 键入为 int 是不是安全?

扩展 Control 以提供始终安全的 Invoke/BeginInvoke 功能是不是合适?

RxSwift:当类具有 disposeBag 属性时,始终使用 [unowned self] 是不是安全?

DotNet高性能设备索引实现(多线程安全+效率)