ChatGPT解决这个技术问题 Extra ChatGPT

GUID 是否 100% 都是唯一的?

GUID 是否 100% 都是唯一的?

它会在多个线程上保持唯一吗?

不,不是 100%... 只是 99,99999999999999999999999999999999999999999999999999999999999999999999999999999% ;)
首先,GUID 不是无限的,这意味着对于“100% 的时间”的字面意思,这意味着无论您生成 GUID 多久,它们始终是唯一的。不是这种情况。此外,由于在最初的实现中不再使用网卡唯一的序列号/id/MAC 来生成密钥的一部分,由于各种原因,GUID 不再是真正全局唯一的。然而,它在当地是独一无二的。换句话说,如果您继续在一台机器上生成 GUID,您将不会得到重复。
@ojrac 我只是选择四舍五入...:P
每次我生成 GUID 时,我都觉得我正在从宇宙中偷走一个。有时我会想到邪恶的人,他们生成的 GUID 比他们需要的多得多,而那些浪费掉的 GUID 是如此孤独,不再被使用或生成......
@asavartsov 我想你会喜欢wasteaguid.info ^_^

C
Community

虽然不能保证每个生成的 GUID 都是唯一的,但唯一键的总数(2128 或 3.4×1038)是如此之大,以至于生成两次相同数字的概率非常小。例如,考虑可观测宇宙,它包含大约 5×1022 颗恒星;然后,每颗星都可以有 6.8×1015 个普遍唯一的 GUID。

Wikipedia

这些是关于如何制作 GUID(对于 .NET)以及如何在正确的情况下获得相同的 guid 的一些好文章。

https://ericlippert.com/2012/04/24/guid-guide-part-one/

https://ericlippert.com/2012/04/30/guid-guide-part-two/

https://ericlippert.com/2012/05/07/guid-guide-part-three/


那么它们不会被称为 UUID 吗? ;)
GUID 是微软对 UUID 标准的具体实现。所以,两者兼而有之。全球唯一 ID 与全球唯一 ID。
从技术上讲,它不是 2^128,因为在 v4 GUID 中,您有一个始终为 4 的十六进制数字(实际上删除了 4 位),并且还保留了进一步的两位。但是,2^122 个有效的 V4 GUID 仍然会留下大约 5x10^36,这对我有用。也为你。每颗星必须接受大约 1.1x10^14 个 GUID。
如果您像我一样,那么您会想知道写出的 2^128 大约是:34,028,236,692,093,846,346,337,460,743,177,000,000。从统计上看,如果你每秒计算 1000 个 GUID,仍然需要数万亿年才能得到一个副本。
我只是觉得读出来很有趣,所以在这里玩得开心:) 三十四十亿二十八十亿二百三十六十亿六百九十二亿九十三亿八百四十六六亿三百四十六万三百三十七千万亿46674043107700000
B
Bura Chuhadar

如果您害怕相同的 GUID 值,请将它们中的两个并排放置。

Guid.NewGuid().ToString() + Guid.NewGuid().ToString();

如果你太偏执,那就放三个。


您必须非常、非常、非常、非常偏执才能附加 3 个 GUID。
@harsimranb 不......非常、非常、非常、非常偏执是 6 个 GUID。偏执是一个附加,非常偏执是两个附加,等等。
@Suamere 我创建了一个网站来计算你的偏执程度jogge.github.io/HowParanoidAmI
@Jogge xD 太棒了,哈哈。在您的表单中出现 9 9 的 999999999 之后,我认为 Paranoia 会破坏我的浏览器。
@Jogge 在我说我是 10,000 级偏执狂之后,您的网站崩溃了。现在我更加偏执
T
Tomalak

简单的答案是肯定的。

Raymond Chen 写了一篇关于 GUID 以及为什么 GUID 的子字符串保证唯一性的great article。本文深入探讨了 GUID 的生成方式以及它们用于确保唯一性的数据,在解释它们的原因为什么时应该花一些时间 :-)


我认为陈的文章是指GUID生成算法的V1,它使用MAC地址&时间戳——当前 V4 使用伪随机数代替:en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm
A
Alex

附带说明一下,我在 Windows XP 中使用 Volume GUID。这是一个非常模糊的分区布局,包含三个磁盘和十四个卷。

\\?\Volume{23005604-eb1b-11de-85ba-806d6172696f}\ (F:)
\\?\Volume{23005605-eb1b-11de-85ba-806d6172696f}\ (G:)
\\?\Volume{23005606-eb1b-11de-85ba-806d6172696f}\ (H:)
\\?\Volume{23005607-eb1b-11de-85ba-806d6172696f}\ (J:)
\\?\Volume{23005608-eb1b-11de-85ba-806d6172696f}\ (D:)
\\?\Volume{23005609-eb1b-11de-85ba-806d6172696f}\ (P:)
\\?\Volume{2300560b-eb1b-11de-85ba-806d6172696f}\ (K:)
\\?\Volume{2300560c-eb1b-11de-85ba-806d6172696f}\ (L:)
\\?\Volume{2300560d-eb1b-11de-85ba-806d6172696f}\ (M:)
\\?\Volume{2300560e-eb1b-11de-85ba-806d6172696f}\ (N:)
\\?\Volume{2300560f-eb1b-11de-85ba-806d6172696f}\ (O:)
\\?\Volume{23005610-eb1b-11de-85ba-806d6172696f}\ (E:)
\\?\Volume{23005611-eb1b-11de-85ba-806d6172696f}\ (R:)
                                     | | | | |
                                     | | | | +-- 6f = o
                                     | | | +---- 69 = i
                                     | | +------ 72 = r
                                     | +-------- 61 = a
                                     +---------- 6d = m

并不是 GUID 非常相似,而是所有 GUID 中都包含字符串“mario”这一事实。这是巧合还是背后有解释?

现在,当 GUID 中的 googling for part 4 时,我发现大约 125.000 次点击量 GUID。

结论:当涉及到卷 GUID 时,它们并不像其他 GUID 那样独特。


还记得 80 年代的超级马里奥兄弟 3 广告吗?所有这些人都在大喊“马里奥!马里奥!马里奥!”环游世界有点扰乱宇宙的随机性。
如果您使用 msiexec 手动卸载 Office 2010,它会列出 office 程序的所有 MSI GUID。它们都拼写为 0FF1CE。似乎微软对如何生成 GUID 有一个相当……松散的解释;)
这些分区 GUID 都是在 2009-12-17 @ 2:47:45 PM UTC 一起创建的。它们对您的机器来说是唯一的,但是将“mario”作为节点标识符是不正确的——这意味着它们不符合 RFC-4122。同样,0FF1CE GUID 属于 RFC-4122 的“NCS 向后兼容性”部分,但 Microsoft 不太可能遵循这些值的 NCS 规则。
我知道,任天堂安全管理局已经破坏了随机数生成器。
也许它与生产矿泉水的公司名称相同(听说他们引领市场)依云。向后拼写天真:-)
T
Tim

它不应该发生。但是,当 .NET 负载过重时,可能会获得重复的 guid。我有两个不同的 Web 服务器使用两个不同的 sql 服务器。我去合并数据,发现我有 1500 万个向导和 7 个重复项。


这仅适用于使用 MAC 地址(而非机器名称)作为 GUID 生成的一部分的 v1 guid。 v4 是事实上的 STD,它不再使用 Mac 地址,而是使用伪随机数。
Guid.NewGuid 始终生成 v4 GUID(并且始终具有)。蒂姆的熵源一定很差。
有没有被复制过?如果是这样,那将是一个巨大的问题。
导入非常大的数据集时也是如此。从大约 10 到 1 亿,您从 Guid.NewGuid 获得重复
@StephanBaltzer 不,that’s simply impossible。如果这确实发生在您身上,那么您的代码中可能存在错误,例如截断 GUID 或混淆了数据行。事实上,NewGuid 实现 中存在错误的可能性要比您真正观察到没有错误的碰撞的可能性更大。但是到目前为止,还没有报告过这样的错误,所以我敢打赌这个问题在你的代码中是一笔不小的数目。
J
Jogge

是的,GUID 应该始终是唯一的。它基于硬件和时间,加上一些额外的位以确保它是独一无二的。我敢肯定,理论上有可能最终得到两个相同的,但在现实世界中极不可能。

这是 Raymond Chen 关于 Guids 的一篇很棒的文章:

https://blogs.msdn.com/oldnewthing/archive/2008/06/27/8659071.aspx ​​​​


这篇文章相当老了,指的是 v1 的 GUID。 v4 不使用硬件/时间,而是使用随机数算法。 en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
此链接已损坏
R
Rob Walker

指南在统计上是唯一的。两个不同客户端生成相同 Guid 的几率非常小(假设 Guid 生成代码中没有错误)。你也可以担心你的处理器由于宇宙射线而出现故障,并决定今天 2+2=5。

分配新 guid 的多个线程将获得唯一值,但您应该知道您正在调用的函数是线程安全的。这是在哪个环境?


取决于您根据规格使用的 guid 版本。一些指南是基于时间和 MAC 地址的。对于 V2 来说,guid 必须在同一台机器上以相同的皮秒生成。这就像将一袋 1000 美分硬币抛向空中,然后它们全都朝上落到一边,堆成一堆。除非生命受到威胁,否则有可能但不太可能将其作为风险提及。
P
Paolo Moretti

Eric Lippert 撰写了一系列非常有趣的关于 GUID 的文章。

世界上有大约 230 台个人计算机(当然还有很多手持设备或非 PC 计算设备,它们或多或少具有相同的计算能力,但让我们忽略这些)。假设我们将世界上所有这些 PC 用于生成 GUID 的任务;如果每个人每秒都可以生成 220 个 GUID,那么仅在大约 272 秒(150 万亿年)之后,您将很有可能与您的特定 GUID 发生冲突。仅仅 30 万亿年之后,碰撞的几率就变得相当高了。

GUID 指南,第一部分

GUID 指南,第二部分

GUID 指南,第三部分


...他在下一段继续说:“但这是在寻找与特定 GUID 的冲突。[...] 因此,如果我们让这 10 亿台 PC 生成 122 位随机 GUID,那么在生成大约 2^61 个 GUID 后,其中两个在某处会发生碰撞,因为我们假设大约 2^30 台机器每秒执行 2^20 个 GUID,我们预计大约 2^20 个 GUID 后会发生碰撞11秒,也就是一个小时左右。” (最后他解释说,当然,生成的 GUID 并不多。)
M
Michael Haren

从理论上讲,不,它们不是唯一的。可以一遍又一遍地生成相同的 guid。然而,它发生的机会是如此之低,以至于你可以假设它们是独一无二的。

我以前读过,机会如此之低,以至于你真的应该强调其他事情——比如你的服务器自发燃烧或代码中的其他错误。也就是说,假设它是独一无二的,并且不构建任何代码来“捕获”重复项——将时间花在更有可能发生的事情上(即其他任何事情)。

made an attempt向我的博客受众(非技术家庭成员)描述 GUID 的用处。从那里(通过维基百科),生成重复 GUID 的几率:

1 分 2^128

1 in 340 undecillion(别担心,undecillion 不在测验中)

1 英寸 3.4 × 10^38

1 in 340,000,000,000,000,000,000,000,000,000,000,000,000


实际上,我不同意“不用担心”,尽管立场不同:如果您确实检测到 GUID 冲突,那么您的应用程序出现了问题。例如,我使用 GUID 来实现幂等性,并且在发送两次命令(使用相同的 GUID)时发生冲突。
C
Cine

似乎没有人提到它发生概率的实际数学。

首先,假设我们可以使用整个 128 位空间(Guid v4 仅使用 122 位)。

我们知道在 n 选择中没有得到重复的一般概率是:

(1-1/2128)(1-2/2128)...(1-(n-1)/2128)

因为 2128 远大于 n,我们可以将其近似为:

(1-1/2128)n(n-1)/2

因为我们可以假设 n 远大于 0,我们可以将其近似为:

(1-1/2128)n^2/2

现在我们可以将其等同于“可接受的”概率,比如说 1%:

(1-1/2128)n^2/2 = 0.01

我们解决 n 并得到:

n = sqrt(2* log 0.01 / log (1-1/2128))

哪个 Wolfram Alpha 为 5.598318 × 1019

从这个数字来看,让我们以 10000 台机器为例,每台机器都有一个 4 核 CPU,运行 4Ghz 并花费 10000 个周期来生成一个 Guid,并且什么都不做。然后他们需要大约 111 年才能生成副本。


我已将您的帖子编辑为 this post - 如果我做错了,请编辑;)。
嗨@Cine,我有权编辑你的回复,但我选择不这样做,因为我想有机会让你先反驳它,如果我不这样做,我可能会在一个月后正式改变它没有收到你的消息。我相当肯定你的数学是错误的。确定 1% 机会的真正方程式是:((2^128 - 1) / 2 ^128) ^ ( (n (n-1)) / 2) = .01。你的指数是错误的。它不只是 n。当您生成“n”个向导时,您需要 C(n,2)(又名 (n*(n-1))/2) 来计算所有组合。浏览此处获取更多信息
谢谢Cine,我最终也接近了n^2/2,因为它太大了:)
10000 台机器需要 111 年才能生成每一个可能的 GUID,然后生成一个副本。然而,在所有可能的 GUID 生成之前很久就会发生重复。我认为大致的时间范围将取决于 GUID 生成过程的“随机性”程度。
@GeorgeK我认为您误解了... 10000 台机器需要 111 年才能有 1% 的机会遇到重复。但是,是的,这个数学当然假设随机生成器是完全随机的。
C
Community

来自http://www.guidgenerator.com/online-guid-generator.aspx

什么是 GUID? GUID(或 UUID)是“全局唯一标识符”(或“通用唯一标识符”)的首字母缩写词。它是一个 128 位整数,用于标识资源。 GUID 一词通常由使用 Microsoft 技术的开发人员使用,而 UUID 则在其他任何地方使用。 GUID 有多独特? 128 位足够大,生成算法也足够独特,如果在 1 年内每秒生成 1,000,000,000 个 GUID,则重复的概率仅为 50%。或者,如果地球上的每个人都生成了 600,000,000 个 GUID,那么重复的概率只有 50%。


50%的重复几率不是高到足以引起恐惧吗?
@disklosr 是的,如果您的系统每秒生成 10 亿个 GUID,这足以引起恐惧。在极不可能的情况下,您生成该数量然后只需将两个 GUID 链接在一起......
K
Konrad Rudolph

GUID 是否 100% 都是唯一的?

不能保证,因为有几种生成方法。但是,您可以尝试计算创建两个相同 GUID 的机会,然后您就会明白:一个 GUID 有 128 位,因此,有 2128 个不同的 GUID - 很多 比已知宇宙中的星星还要多。阅读 wikipedia article 了解更多详情。


J
Jakub Šturc

MSDN

新 Guid 的值全为零或等于任何其他 Guid 的概率非常低。


D
DrPizza

如果您的系统时钟设置正确并且没有环绕,并且您的 NIC 有自己的 MAC(即您没有设置自定义 MAC)并且您的 NIC 供应商没有回收 MAC(他们不应该这样做)但已知会发生),并且如果您的系统的 GUID 生成功能正确实现,那么您的系统将永远不会生成重复的 GUID。

如果地球上每个生成 GUID 的人都遵循这些规则,那么您的 GUID 将是全球唯一的。

在实践中,违反规则的人数很少,他们的 GUID 不太可能“逃脱”。冲突在统计上是不可能的。


这仅适用于 v1 指南。 v4 是事实上的 STD,它不再使用 Mac 地址,而是使用伪随机数。
“那么您的系统将永远不会生成重复的 GUID”即使您所说的 v1 guid 遵循了所有规则,您的系统仍然可以生成重复项。当您说“冲突在统计上是不可能的”时,您在底部更正确。
M
Mohit Jain

我遇到了重复的 GUID。

我使用 Neat Receipts 桌面扫描仪,它带有专有的数据库软件。该软件具有同步到云的功能,但我在同步时一直出错。仔细看日志,发现了令人敬畏的一行:

"errors":[{"code":1,"message":"creator_guid: 已被占用","guid":"C83E5734-D77A-4B09-B8C1-9623CAC7B167"}]}

我有点难以置信,但可以肯定的是,当我找到进入我本地的整洁数据库的方法并删除包含该 GUID 的记录时,错误停止发生。

所以用轶事证据回答你的问题,不。可以复制。但它发生的原因很可能不是偶然的,而是由于没有以某种方式遵守标准做法。 (我只是没那么幸运)但是,我不能肯定地说。这不是我的软件。

他们的客户支持非常有礼貌和乐于助人,但他们之前一定从未遇到过这个问题,因为在与他们通了 3 个多小时的电话后,他们没有找到解决方案。 (FWIW,Neat 给我留下了深刻的印象,这个故障,无论多么令人沮丧,并没有改变我对他们产品的看法。)


不要相信你有重复。可能还涉及其他一些问题,例如数字不是真正随机的或同步过程中的问题,或者系统尝试记录两次等。软件问题比您获得重复的 GUID 更有可能。
A
Adithya Sai

为了获得更好的结果,最好的方法是在 GUID 后面加上时间戳(只是为了确保它保持唯一)

Guid.NewGuid().ToString() + DateTime.Now.ToString();

如果您在同一秒内发生两次碰撞怎么办?
这是最坏的情况,但我们不能同时生成相同的两个 Guid。
他们在某个地方争辩说,应该从 SO 的答案中复制,而不是问题,但我现在不太确定......
Guid.NewGuid().ToString().Replace("-", "") + DateTime.Now.Ticks .... 唯一性没有问题,可以用作主键
E
Eric Elliott

GUID 算法通常根据 v4 GUID 规范实现,该规范本质上是一个伪随机字符串。可悲的是,这些属于“可能不唯一”的类别,来自维基百科(我不知道为什么这么多人忽略这一点):“......其他 GUID 版本具有不同的唯一性属性和概率,从保证唯一性到可能的非唯一性。”

V8 的 JavaScript Math.random() 的伪随机属性在唯一性方面非常糟糕,碰撞通常仅在几千次迭代后发生,但 V8 并不是唯一的罪魁祸首。我已经看到使用 v4 GUID 的 PHP 和 Ruby 实现的真实 GUID 冲突。

因为跨多个客户端和服务器集群扩展 ID 生成变得越来越普遍,熵受到了很大的打击——相同的随机种子被用于生成 ID 升级的机会(时间通常被用作随机种子在伪随机生成器中),并且 GUID 冲突从“可能不唯一”升级为“很可能造成很多麻烦”。

为了解决这个问题,我着手创建一个可以安全扩展的 ID 算法,并更好地保证防止碰撞。它通过使用时间戳、内存中的客户端计数器、客户端指纹和随机字符来实现。各种因素的组合产生了一种特别抗碰撞的附加复杂性,即使您在多个主机上扩展它:

http://usecuid.org/


R
Robert Jørgensgaard Engdahl

在多线程/多进程单元测试期间,我经历过 GUID 不是唯一的(也是?)。我想这与伪随机生成器的相同播种(或缺少播种)有关,在所有其他情况相同的情况下。我用它来生成唯一的文件名。我发现操作系统在这方面做得更好:)

拖钓警报

您询问 GUID 是否 100% 唯一。这取决于它必须是唯一的 GUID 的数量。随着 GUID 的数量接近无穷大,重复 GUID 的概率接近 100%。


m
mszil

在更一般的意义上,这被称为“生日问题”或“生日悖论”。维基百科在以下位置有一个很好的概述:Wikipedia - Birthday Problem

粗略地说,池大小的平方根是一个粗略的近似值,即您可以预期 50% 的重复几率。文章包括一个池大小和各种概率的概率表,包括 2^128 的一行。因此,对于 1% 的碰撞概率,您会期望随机选择 2.6*10^18 个 128 位数字。 50% 的机会需要 2.2*10^19 次选择,而 SQRT(2^128) 是 1.8*10^19。

当然,这只是真正随机过程的理想情况。正如其他人所提到的,很多东西都依赖于随机方面——生成器和种子到底有多好?如果有一些硬件支持来协助这个过程会很好,这将更加防弹,除了任何东西都可以被欺骗或虚拟化。我怀疑这可能是不再包含 MAC 地址/时间戳的原因。


我认为MAC问题是匿名的。我相信以一种可以逆转的方式使用诸如 MAC 地址之类的标识符是一个隐私问题。我相信硬件中的真正随机非常困难? Cloudflare 使用了一个摄像头和一排熔岩灯,但是我认为,如果对物理有精确的理解,那也不是随机的吗? Cloudflares 熔岩灯 RNG:popularmechanics.com/technology/security/news/a28921/…
B
Baba Khedkar

“GUID 是 100% 唯一的吗?”的答案只是“不”。

如果您想要 GUID 的 100% 唯一性,请执行以下操作。生成 GUID 检查该 GUID 是否存在于您正在寻找唯一性的表列中,如果存在则转到步骤 1,否则步骤 4 将此 GUID 用作唯一。

生成 GUID

检查该 GUID 是否存在于您正在寻找唯一性的表列中

如果存在则转到第 1 步,否则第 4 步

将此 GUID 用作唯一的。


这并不意味着它是独一无二的。您的算法不会将新创建的 GUID 保存在表中。下次创建 GUID 时,它可能会与之前的 GUID 发生冲突。如果您要将 GUID 插入到表中,则 GUID 可能已经被另一个对等方插入,在您检查唯一性并将 GUID 插入到表中之间。 GUID 仅在您的系统中是唯一的,因此如果您要导入或合并两个数据库,它们仍然可能发生冲突。当您无权访问中心化数据库时,也经常使用 GUID。如果你有为什么不从数据库中提取一个 ID 呢?
T
Trong Hiep Le

最困难的部分不是生成重复的 Guid。

最难的部分是设计一个数据库来存储所有生成的数据库,以检查它是否真的重复。

来自维基:

例如,为了有 50% 的概率至少发生一次冲突,需要生成的随机版本 4 UUID 的数量为 2.71 quintillion,计算如下:

enter image description here

这个数字相当于每秒生成 10 亿个 UUID 大约 85 年,一个包含这么多 UUID 的文件(每个 UUID 16 个字节)大约是 45 艾字节,比目前存在的最大数据库大很多倍,数百 PB 的数量级


B
Benjamin Roberts

GUID 代表全球唯一标识符

简而言之:(线索就在名字里)

详细说明:GUID 的设计是独一无二的;它们是使用基于计算机时钟和计算机本身的随机方法计算的,如果您在同一台机器上以相同的毫秒时间创建多个 GUID,它们可能会匹配,但对于几乎所有正常操作,它们应该被认为是唯一的。


W
William M. Rawls

足够的 GUID 可以为可见宇宙中每颗恒星周围的每个假设行星上的每个假设沙粒分配一个。

足以让如果世界上每台计算机在 200 年内每秒生成 1000 个 GUID,则可能(可能)会发生碰撞。

考虑到 GUID 的当前本地使用数量(例如,每个数据库每个表一个序列),对于我们有限的生物(以及寿命通常不到 10 年,如果不是一两年的机器)来说,这极不可能成为问题用于手机)。

...我们现在可以关闭这个线程吗?


W
Wai Ha Lee

我认为,当人们将自己的想法和恐惧隐藏在统计数据中时,他们往往会忘记显而易见的事情。如果一个系统确实是随机的,那么您最不可能期望的结果(例如全为 1)与任何其他意外值(例如全零)的可能性相同。这两个事实都不能阻止这些连续发生,也不能在第一对样本中发生(即使这在统计上是“真正令人震惊的”)。这就是衡量机会的问题:它完全忽略了关键性(和坏运气)。

如果曾经发生过,结果是什么?你的软件停止工作了吗?有人受伤吗?有人死吗?世界会爆炸吗?

临界性越极端,“概率”这个词在口中的表现就越糟糕。最后,当您(主观地)认为您的特定关键性(以及您对“幸运”的感觉)不可接受时,链接 GUID(或对它们进行异或,或其他)是您所做的。如果它可以终结世界,那么请代表我们所有未参与大型强子对撞机核实验的人,不要使用 GUID 或其他任何不确定的东西!