GUID是否在100%的时间内是唯一的?


519

GUID是否在100%的时间内是唯一的?

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


264
不,不是100%...仅99,99999999999999999999999999999999999999999999999999999999999999999999999%;)
JohannesH

52
首先,GUID不是无限的,这意味着对于“ 100%的时间”的字面含义,这意味着无论您继续生成GUID多长时间,它们始终是唯一的。不是这种情况。同样,由于原来的实现方式(由于各种原因)不再使用网卡唯一的序列号/ id / MAC来生成密钥的一部分,因此,GUID不再真正具有全局唯一性。但是,它在本地是唯一的。换句话说,如果您继续在一台计算机上生成GUID,则不会得到重复的副本。
Lasse V. Karlsen

36
@ojrac我只是选择四舍五入...:P
JohannesH,2010年

403
每次生成GUID时,我都觉得自己正在从宇宙中窃取一个。有时我会想到邪恶的人生成了比他们需要的GUID多得多的GUID,而那些浪费的GUID是如此寂寞,不再被使用或再次生成...
asavartsov

29
@asavartsov我想您会喜欢wasteaguid.info ^ _ ^
Navin

Answers:


431

虽然不能保证每个生成的GUID都是唯一的,但是唯一密钥的总数(2 128或3.4×10 38)是如此之大,以至于相同密钥两次生成两次的概率非常小。例如,考虑可观测的宇宙,它包含大约5×10 22个 恒星;这样,每颗星就可以拥有6.8×10 15个通用的GUID。

来自维基百科


这些是有关如何制作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/

​​


115
难道它们不被称为UUID吗?;)
Arafangion's 2009年

28
GUID是Microsoft对UUID标准的特定实现。因此,两者都是。全球唯一ID与全球唯一ID。
亚当·戴维斯

40
从技术上讲,它不是2 ^ 128,因为在v4 GUID中,您有一个十六进制数字始终为4(有效地去除了4位),并且还保留了另外两位。但是,仍然有2 ^ 122个有效的V4 GUID留下大约5x10 ^ 36的空间,这将对我有用。对你也是。每颗星将必须仅接受大约1.1x10 ^ 14 GUID。
安德鲁·谢兰斯基

67
如果您像我,那么您将想知道2^128写出来的内容大约是:34,028,236,692,093,846,346,337,460,743,177,000,000。从统计上讲,如果您每秒计算1000个GUID,则仍然需要数万亿年的时间才能获得副本。
实体2012年

26
我只是觉得读起来很有趣,所以这里有很多好玩的家伙:) 34一百二十万一百二十八亿三千六百六十三六百三十六四百六十万亿七千三百三十三亿一千七百七十万
贾巴尔

85

如果您担心相同的GUID值,则将其中两个彼此相邻。

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

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


63
要附加3个GUID,您必须非常非常非常偏执。
harsimranb

25
@harsimranb不……非常非常非常偏执,是6个GUID。偏执狂是一个附加的,非常偏执狂是两个附加的,等等
Suamere

36
@Suamere我创建了一个网站来计算您的偏执程度jogge.github.io/HowParanoidAmI
Jogge

3
@Jogge xD太神奇了,大声笑。999999999在您的表格中以9 9表示之后,我认为Paranoia将a-splode我的浏览器。
Suamere

66

简单的答案是。

Raymond Chen 在GUID上写了一篇很棒的文章,以及为什么不能保证GUID的子字符串是唯一的。本文深入介绍了GUID的生成方式以及它们用于确保唯一性的数据,这在解释它们为什么如此时应做一些工作:-)


23
我认为Chen的文章指的是GUID生成算法的V1,该算法使用MAC地址和时间戳记-当前的V4使用伪随机数代替:en.wikipedia.org/wiki/Globally_Unique_Identifier#Algorithm
Barrett

2
链接已
消失-403


39

附带说明一下,我正在使用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中搜索第4部分时,我发现批量GUID的点击量约为125.000。

结论:关于卷GUID,它们不像其他GUID那样独特。


31
还记得80年代的《超级马里奥兄弟3》广告吗?所有这些人大喊“马里奥!马里奥!马里奥!” 全世界都在破坏宇宙的随机性。
MGOwen

24
如果使用手动卸载Office 2010 msiexec,它将列出Office程序的所有MSI GUID。他们都拼了0FF1CE。似乎微软对如何生成GUID有相当...宽松的解释;)
Mark Henderson

3
这些分区GUID都是在UTC于2009-12-17 @ 2:47:45 PM一起创建的。它们对于您的机器是唯一的,但是将“ mario”作为节点标识符不正确-这意味着它们不符合RFC-4122。同样,0FF1CEGUID属于RFC-4122的“ NCS向后兼容性”部分,但是Microsoft不太可能遵循这些值的NCS规则。
Stephen Cleary

16
我知道,任天堂安全管理局已经破坏了随机数发生器。
MetaGuru 2014年

1
也许是与生产矿泉水的公司名称相同的球场(听说他们领导了市场)依云。向后拼写会得到天真:-)
Mariusz

31

它不应该发生。但是,当.NET负担很重时,就有可能获得重复的引导。我有两个使用两个不同sql服务器的不同Web服务器。我去合并数据,发现我有1500万盾和7个副本。


1
在两台不同的机器上怎么可能?我以为GUID的一部分是机器名称?(不争论……只是问)
约翰·克鲁兹

8
这仅适用于使用MAC地址(而不是计算机名称)作为GUID生成一部分的v1引导。v4(实际上是STD)不再使用Mac地址,而是使用伪随机数。
Xander

14
Guid.NewGuid始终生成v4 GUID(并且始终具有)。蒂姆一定有非常差的熵源。
Stephen Cleary

1
那曾经被复制过吗?如果是这样,那将是一个巨大的问题。
Zyo

1
在导入非常大的数据集时也是如此。从大约10到1亿您可以从Guid.NewGuid
Stephan Baltzer

28

是的,GUID应该始终是唯一的。它基于硬件和时间,再加上一些额外的位以确保其唯一性。我相信从理论上讲,最终可以得到两个相同的对象,但在实际情况中极不可能。

这是雷蒙德·陈(Raymond Chen)在Guids上的精彩文章:

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


5
本文相当老,涉及的是GUID v1。v4不使用硬件/时间,而是使用随机数算法。en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
Mani Gandham

此链接已断开
Marcel


23

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

分配新guid的多个线程将获得唯一的值,但是您应该得到所调用的函数是线程安全的。这是什么环境?


19

埃里克·利珀特(Eric Lippert)写了一系列非常有趣的有关GUID的文章。

全世界大约有2 30台个人计算机(当然,许多手持设备或非PC计算设备具有或多或少相同的计算能力,但请忽略它们)。假设我们将世界上所有这些PC都用于生成GUID。如果每个人每秒可以生成2 20个 GUID,那么在大约2 72秒(一百五十万亿年)之后,您有可能与您的特定GUID发生碰撞。仅三十万亿年后,碰撞的几率就相当可观。


28
...然后他在下一段中继续说:“但是,这是在寻找与特定GUID的冲突。因此,如果我们让这十亿台PC进行工作,以生成122位随机GUID,在生成大约2 ^ 61个GUID之后,其中两个在某个地方的碰撞会变得非常高。由于我们假设大约2 ^ 30台机器每秒执行2 ^ 20个GUID,因此我们希望在大约2 ^后发生冲突11秒,大约一个小时。” (最后,他解释说,当然不会生成很多GUID。)
Arjan 2013年

16

从理论上讲,不,它们不是唯一的。可能一遍又一遍地生成相同的GUID。但是,发生这种情况的机会非常低,您可以认为它们是独一无二的。

我之前读过,机会很少,您真的应该强调其他事情-例如服务器自发燃烧或代码中的其他错误。也就是说,假设它是唯一的,并且不构建任何代码来“捕获”重复项-将您的时间花在更可能发生的事情上(即其他任何事情)。

试图向我的博客读者(非技术家庭成员)描述GUID的有用性。从那里(通过Wikipedia),生成重复GUID的几率:

  • 1分2 ^ 128
  • 340十亿分之一(不用担心,十亿不参与测验)
  • 1吋3.4×10 ^ 38
  • 340,000,000,000,000,000,000,000,000,000,000,000,000中的1

1
实际上,我不同意“不用担心”,尽管有不同的立场:如果您确实检测到GUID冲突,则说明您的应用程序出现了问题。例如,我已经使用GUID进行幂等,并且在两次发送命令(使用相同的GUID)时发生冲突。
洪敬轩

9

似乎没有人提及发生这种可能性的实际数学方法。

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

我们知道未在n选秀中重复的一般概率为:

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

因为2 128比得多得多n,所以我们可以将其近似为:

(1-1 / 2 128n(n-1)/ 2

并且因为我们可以假设n比0大得多,所以我们可以近似地得出:

(1-1 / 2 128n ^ 2/2

现在,我们可以将其等同于“可接受的”概率,假设为1%:

(1-1 / 2 128n ^ 2/2 = 0.01

我们要解决的问题n并得到:

n = sqrt(2 *日志0.01 /日志(1-1 / 2 128))

Wolfram Alpha变为5.598318×10 19

为了弄清楚这个数字,让我们拿10000台机器(每台机器有一个4核CPU),执行4Ghz并花费10000个周期来生成Guid,然后什么也不做。然后,大约需要111年才能生成副本。


这篇文章之后,我已经编辑了您的文章 -如果我做错了,请编辑;)。
shA.t

@Cine,您好,我有权编辑您的回复,但选择不这样做,因为我想让您有机会先反驳它,如果我不这样做,我可能会用一个月的时间来正式更改它没收到你的消息。我相当确定您的数学是错误的。确定1%机会的真实方程式是:(((2 ^ 128-1)/ 2 ^ 128)^((n(n-1))/ 2)= 0.01。您的指数是错误的。不只是n 生成“ n”个引导时,需要C(n,2)(又名(n *(n-1))/ 2)来计算所有组合。有关更多信息,请参见此处
活力

谢谢Cine,我也最终接近了n ^ 2/2,因为它是如此之大:)
活力

生成每一个可能的GUID,然后生成一个副本,将需要10000台计算机111年。但是,在所有可能的GUID生成之前很久就会发生重复。我认为大概的时间范围将取决于GUID生成过程的“随机性”。
乔治·K

@GeorgeK我想您误会了……111台机器需要10000台机器,才能有1%的机会遇到重复。但是是的,当然,这种数学假设是随机生成器是完全随机的。
Cine

7

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

什么是GUID?

GUID(或UUID)是“全局唯一标识符”(或“通用唯一标识符”)的首字母缩写。它是用于标识资源的128位整数。GUID术语通常由使用Microsoft技术的开发人员使用,而UUID则在其他任何地方使用。

GUID有多独特?

128位足够大,并且生成算法也足够独特,如果在一年内每秒生成1,000,000,000 GUID,则重复的可能性仅为50%。或者,如果地球上的每个人都产生600,000,000 GUID,那么复制的可能性只有50%。


7
是不是有50%的机会有足够的机会引起恐惧?
disklosr 2015年

1
@disklosr是的,如果您的系统每秒生成10亿个GUID,就足以引起恐惧。万一发生这种情况,您只需生成两个GUID,就可以了……
maxshuty

5

我遇到了重复的GUID。

我使用的是Neat Receipts台式扫描仪,它带有专有的数据库软件。该软件具有“同步到云”功能,并且在同步时一直出现错误。日志上的秃鹰露出了那条令人敬畏的台词:

“错误”:[{“代码”:1,“消息”:“ creator_guid:已被使用”,“ guid”:“ C83E5734-D77A-4B09-B8C1-9623CAC7B167”}]}}

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

因此,以传闻证据回答您的问题,不是。可以重复。但是,发生这种情况的原因很可能不是偶然的,而是由于没有遵循某种标准惯例。(我不是那么幸运)但是,我不能肯定地说。这不是我的软件。

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


19
不相信你有重复。可能还涉及其他方面,例如数字不是真正随机的,也不是同步过程中的问题,或者系统尝试记录两次,等等。软件问题比获得重复的GUID更有可能。
orad 2013年


4

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

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

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


11
这仅适用于v1向导。v4(实际上是STD)不再使用Mac地址,而是使用伪随机数。
Pita.O 2010年

1
“那么您的系统将永远不会生成重复的GUID”即使您所说的v1 guid遵循了所有规则,您的系统仍然可以生成重复的GUID。当您声明“冲突在统计上是不可能的”时,您在底部更加正确。
尼克·梅尔德鲁姆

3

GUID是否在100%的时间内是唯一的?

不能保证,因为有多种生成方法。但是,您可以尝试计算创建两个相同的GUID的机会,然后您就会明白:一个GUID具有128位,因此,有2 128个不同的GUID – 远远超过已知宇宙中的恒星。阅读Wikipedia文章以了解更多详细信息。


2

从更一般的意义上讲,这被称为“生日问题”或“生日悖论”。Wikipedia在以下方面有一个很好的概述: Wikipedia-生日问题

用非常粗略的话说,池大小的平方根是您可以期望有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/…–
杰夫·布洛克

2

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

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

如果您在同一秒内发生两次碰撞该怎么办?
李慧夏

那是最坏的情况,但仍然不能同时生成两个相同的Guid。
Adithya Sai

他们在某个地方争论说,应该从SO的答案而不是问题中复制出来,但我现在不确定……。–
Marcel

1

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

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

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

为了解决这个问题,我着手创建一个ID算法,该算法可以安全扩展,并更好地防止冲突。它通过使用时间戳,内存中的客户端计数器,客户端指纹和随机字符来实现。因素的组合会产生额外的复杂性,即使您在多个主机上进行扩展,也特别能抵御冲突:

http://usecuid.org/


1

我经历了GUID在多线程/多进程单元测试期间不是唯一的(也是吗?)。我猜想这与在其他所有条件相同的情况下,伪随机生成器的相同种子(或没有种子)有关。我用它来生成唯一的文件名。我发现该操作系统在执行此操作方面要好得多:)

拖钓警报

您询问GUID是否100%唯一。这取决于GUID数量必须是唯一的。当GUID的数量接近无穷大时,重复GUID的可能性接近100%。


1

答案是“ GUID是100%唯一的吗?” 简直是“ No”

  • 如果要GUID具有100%的唯一性,请执行以下操作。

    1. 生成GUID
    2. 检查要查找唯一性的表列中是否存在GUID
    3. 如果存在,则转到步骤1,否则转到步骤4
    4. 将此GUID用作唯一。

这不会使其唯一。您的算法不会将新创建的GUID保存在表中。下次创建GUID时,它可能会与之前的冲突。如果要将GUID插入表中,则在检查唯一性并将GUID插入表之间,另一个对等方可能已经插入了GUID。GUID仅在您的系统内是唯一的,因此,如果要导入或合并两个数据库,它们仍可能会冲突。当您无权访问离心数据库时,也经常使用GUID。如果有,为什么不从数据库中提取一个ID?
Jogge

0

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

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

从维基百科:

例如,为了产生至少一次碰撞的50%概率而需要生成的随机版本4 UUID的数量为2.71亿五千万,计算如下:

在此处输入图片说明

此数字等效于在大约85年的时间里每秒生成10亿个UUID,而包含这么多UUID(每个UUID为16字节)的文件大约为45 EB,比当前最大的数据库大很多倍。数百PB的数量级


0

GUID代表全局唯一标识符

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

详细信息:GUID设计为唯一;它们是根据计算机时钟和计算机​​本身使用随机方法计算的,如果在同一台计算机上同一毫秒创建多个GUID,则它们可能会匹配,但对于几乎所有正常操作,都应将它们视为唯一的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.