GUID 100%是唯一的吗?
它会在多个线程中保持唯一吗?
而每个生成的GUID不是 保证是唯一的,总数 唯一键数(2128或 3.4×1038)是如此之大,相同的数字的概率是 生成两次是非常小的。为 例如,考虑可观察对象 宇宙,其中包含约5×1022 星星;每颗恒星都有可能 6.8×1015通用唯一guid。
从# EYZ0。
这是一些关于如何创建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/
是的,GUID应该总是唯一的。它是基于硬件和时间,加上一些额外的位,以确保它是唯一的。我相信理论上有可能得到两个一模一样的,但在现实场景中极不可能。
以下是Raymond Chen关于Guids的一篇很棒的文章:
https://blogs.msdn.com/oldnewthing/archive/2008/06/27/8659071.aspx < / p >
简单的答案是肯定的。
Raymond Chen写了一个关于guid的伟大的文章,以及为什么guid的子字符串是不保证唯一的。这篇文章深入探讨了guid的生成方式和他们用来确保唯一性的数据,这应该在解释为什么他们是:-)
# EYZ0:
新Guid的值全为零或等于任何其他Guid的概率非常低。
不能保证,因为有几种方法可以生成一个。然而,您可以尝试计算创建两个完全相同的GUID的机会,您会得到这样的想法:一个GUID有128位,因此,有2个128不同的GUID - 多比已知宇宙中的恒星还要多。阅读维基百科的文章了解更多细节。
从统计上看,向导是独一无二的。两个不同的客户端生成相同Guid的几率非常小(假设Guid生成代码中没有错误)。你也可以担心由于宇宙射线导致的处理器故障,并决定今天2+2=5。
分配新guid的多个线程将获得唯一的值,但您应该知道您正在调用的函数是线程安全的。这是在哪个环境中?
理论上讲,不,它们不是唯一的。可以反复生成相同的guid。然而,这种情况发生的几率非常低,你可以假设它们是独一无二的。
我以前读到过,这种可能性非常低,你真的应该关注其他事情——比如你的服务器自燃或代码中的其他错误。也就是说,假设它是唯一的,不要构建任何“捕获”重复的代码——把时间花在更有可能发生的事情上(即任何东西 else)。
我尝试过向我的博客读者(非技术家庭成员)描述guid的有用性。从那里(通过维基百科),生成重复GUID的几率:
如果你的系统时钟设置正确,没有被环绕,如果你的网卡有自己的MAC(即你没有设置自定义MAC),你的网卡供应商没有回收MAC(他们不应该这样做,但已经知道发生了),如果你的系统的GUID生成功能正确实现,那么你的系统将永远不会生成重复的GUID。
如果地球上每个生成guid的人都遵循这些规则,那么您的guid将是全局唯一的。
在实践中,违反规则的人数很少,他们的guid不太可能“逃脱”。冲突在统计上是不可能发生的。
顺便说一句,我在Windows XP中使用了Volume guid。这是一个非常模糊的分区布局,有3个磁盘和14个卷。
\\?\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”。这是巧合还是另有原因?
现在,当搜索第4部分在GUID中,我发现大约有125.000个与卷GUID的点击。
当谈到卷guid时,它们不像其他guid那样唯一。
这种情况不应该发生。然而,当. net负载过重时,可能会得到重复的guid。我有两个不同的web服务器使用两个不同的sql服务器。我去合并数据,发现我有1500万个guids和7个副本。
Eric Lippert写了一系列关于guid的非常有趣的文章。
世界上大约有230.个人电脑 当然很多手持设备或非pc计算设备 差不多是相同水平的计算能力,但让我们忽略 那些)。假设我们把世界上所有的电脑 生成guid的任务;如果每个都能生成2个20. guid 然后在大约272秒之后—— 150 万亿年——你将有非常高的机会生成一个 与您的特定GUID冲突。碰撞的概率 在30万亿年之后已经很不错了
我经历了一个重复的GUID。
我使用的是Neat收据桌面扫描仪,它自带专有数据库软件。该软件有一个同步到云的功能,我总是在同步时得到一个错误。浏览一下日志,你会发现这句话非常棒:
"errors":[{"code":1,"message":"creator_guid: is already . 了”、“guid”:“c83e5734 d77a - 4 - b09 b8c1 - 9623 cac7b167”}]}< / p >
我有点难以置信,但可以肯定的是,当我找到进入本地网络数据库的方法并删除包含该GUID的记录时,错误就停止了。
所以用轶事证据来回答你的问题,没有。副本是可能的。但它发生的原因很可能不是由于偶然,而是由于标准的做法在某种程度上没有得到遵守。(我只是没有那么幸运)然而,我不能肯定。这不是我的软件。
他们的客户支持非常有礼貌和乐于助人,但他们以前肯定从未遇到过这个问题,因为在与他们电话交谈3个多小时后,他们没有找到解决方案。(总之,Neat给我留下了深刻的印象,这个小故障虽然令人沮丧,但并没有改变我对他们产品的看法。)
GUID算法通常根据v4 GUID规范实现,它本质上是一个伪随机字符串。可悲的是,这些都属于“可能非唯一”的类别,来自维基百科(我不知道为什么这么多人忽略了这一点):“……其他GUID版本有不同的唯一性属性和概率,从保证唯一性到可能的非唯一性。”
V8的JavaScript Math.random()的伪随机属性在唯一性方面非常糟糕,通常在几千次迭代之后就会发生冲突,但V8并不是唯一的罪魁祸首。我曾经使用PHP和Ruby实现的v4 GUID在现实世界中遇到过GUID冲突。
Math.random()
因为在多个客户端和服务器集群上扩展ID生成变得越来越普遍,熵会受到很大的冲击——使用相同的随机种子生成ID的几率会增加(在伪随机生成器中,时间经常被用作随机种子),GUID冲突也会从“可能不是唯一的”升级为“很可能造成很多麻烦”。
为了解决这个问题,我开始创建一个可以安全扩展的ID算法,并更好地保证不发生碰撞。它通过使用时间戳、内存中的客户端计数器、客户端指纹和随机字符来实现这一点。这些因素的组合产生了一种附加的复杂性,它特别抗碰撞,即使你将它扩展到多个主机:
< a href = " http://usecuid.org/ " rel =“nofollow”> http://usecuid.org/ < / >
从# EYZ0
什么是GUID? GUID(或UUID)是“全球唯一标识符”(或“全球唯一标识符”)的首字母缩写。128位整数,用于标识资源。术语GUID通常由使用微软技术的开发人员使用,而UUID则用于其他任何地方。 GUID有多独特? 128位足够大,生成算法足够独特,如果每秒生成1,000,000,000个guid,持续1年,重复的概率将只有50%。或者,如果地球上的每个人都产生600,000,000个guid,那么只有50%的概率是重复的。
什么是GUID?
GUID(或UUID)是“全球唯一标识符”(或“全球唯一标识符”)的首字母缩写。128位整数,用于标识资源。术语GUID通常由使用微软技术的开发人员使用,而UUID则用于其他任何地方。
GUID有多独特?
128位足够大,生成算法足够独特,如果每秒生成1,000,000,000个guid,持续1年,重复的概率将只有50%。或者,如果地球上的每个人都产生600,000,000个guid,那么只有50%的概率是重复的。
如果你害怕相同的GUID值,那么把它们放在一起。
Guid.NewGuid().ToString() + Guid.NewGuid().ToString();
如果你太多疑,那就放三个。
似乎没有人提到它发生概率的实际数学计算。
首先,让我们假设我们可以使用整个128位空间(Guid v4只使用122位)。
我们知道在n中没有得到重复的一般概率是:
n
(1 - 1/2 # EYZ0) (1-2/2 # EYZ0)……(1 - (n - 1) / 2 # EYZ0)
因为2128比n大得多,我们可以将其近似为:
(1 - 1/2 # EYZ0) # EYZ1
因为我们可以假设n比0大得多,我们可以将其近似为:
现在我们可以将其等同于“可接受的”概率,假设是1%:
(1-1/2# eyz0)# eyz1 = 0.01
我们解决了n并得到:
n =√(2* log 0.01 / log (1-1/2128))
哪个Wolfram Alpha可以成为5.598318 × 1019
为了更好地理解这个数字,让我们以10000台机器为例,每台机器都有一个4核CPU,工作4Ghz,花费10000个周期来生成一个Guid,其他什么都不做。然后需要大约111年才能产生一个副本。
在多线程/多进程单元测试期间,我经历过guid不是唯一的(也是?)我想这与所有其他条件相同的情况下,伪随机生成器的相同播种(或缺乏播种)有关。我用它来生成唯一的文件名。我发现操作系统在这方面做得更好:)
你问guid是否100%唯一。这取决于它在guid中必须是唯一的。当guid的数量接近无穷大时,重复guid的概率接近100%。
粗略地说,池大小的平方根是一个粗略的近似值,即您可以期望有50%的重复机会。这篇文章包含了一个关于池大小和各种概率的概率表,包括2^128的一行。所以对于1%的碰撞概率,你可以随机选择2.6*10^18个128位数字。50%的概率需要2.2*10^19次选择,而根号(2^128)是1.8*10^19次选择。
当然,这只是一个真正随机过程的理想情况。正如其他人提到的,很多事情都取决于随机方面——生成器和种子有多好?如果有一些硬件支持来帮助这个过程,那就太好了,这将更加防弹,除非任何东西都可能被欺骗或虚拟化。我怀疑这可能是MAC地址/时间戳不再被合并的原因。
GUID是100%唯一的吗?的答案就是“不”。
如果你想要GUID的100%唯一性,然后执行以下操作。
最难的部分不是生成重复的Guid。
最难的部分是设计一个数据库来存储所有生成的数据,以检查它是否实际上是重复的。
从维基:
例如,为了有至少一次碰撞的50%概率,需要生成的随机版本4 uuid的数量为2.71 quintillion,计算如下:
enter image description here
这个数字相当于在大约85年的时间里每秒生成10亿个UUID,而包含这么多UUID的文件(每个UUID 16个字节)大约是45艾字节,比目前存在的最大数据库(几百pb量级)大很多倍
GUID代表全局唯一标识符
为了获得更好的结果,最好的方法是将GUID与时间戳附加在一起(只是为了确保它保持唯一)
Guid.NewGuid().ToString() + DateTime.Now.ToString();
足够的guid来为可见宇宙中每一颗恒星周围的每一颗假设行星上的每一颗假设沙粒分配一个guid。
以至于如果世界上的每台计算机每秒生成1000个guid,持续200年,就可能发生碰撞。
考虑到当前guid的本地使用数量(例如,每个数据库每个表一个序列),这对于我们这些有限的生物来说是非常不可能成为问题的(对于手机来说,寿命通常不到十年,如果不是一两年的话)。
... 我们现在可以结束这个话题了吗?
我认为,当人们把自己的想法和恐惧淹没在统计数据中时,他们往往会忘记显而易见的事情。如果一个系统确实是随机的,那么你最不可能期望的结果(比如全部为1)与任何其他意外值(比如全部为0)的可能性相同。这两种情况都不能防止连续发生,也不能在第一对样本中发生(即使这在统计上是“真正令人震惊的”)。这就是衡量机会的问题所在:它完全忽略了临界性(和坏运气)。
如果真的发生了,结果是什么?你的软件停止工作了吗?有人受伤了吗?有人死了吗?世界会爆炸吗?
临界性越极端,“概率”这个词就越糟糕。坐在嘴里。最后,当你认为(主观上)你的特定关键(和你的“幸运”感觉)是不可接受的时候,链接guid(或XORing他们,或其他什么)是你所做的。如果它能毁灭世界,那么请代表我们所有没有参与大型强子对撞机核试验的人,不要使用guid或任何其他不确定的东西!