GUID碰撞可能吗?
我正在使用SQL Server 2000中的数据库,该数据库使用每个用户使用的GUID来使用它绑定的应用程序。 不知何故,两个用户结束了相同的GUID。 我知道microsoft使用一种algorithm来生成一个随机的GUID,导致碰撞的几率非常低,但是碰撞仍然是可能的吗?
基本上没有。 我认为有人去了你的数据库。 根据您使用的版本GUID,该值可以是唯一的(例如版本1的GUID),也可以是唯一的和不可预知的(对于版本4的GUID)。 他们的NEWID()函数的SQL Server的实现似乎使用一个128位的随机数,所以你不会碰到。
如果碰撞几率为1%,则需要生成大约2,600,000,000,000,000个 GUID。
基本上他们是不可能的! ,机会是天文数字低 。
但是,我是我所知道的世界上唯一一个有一次GUID扫描 ( yep !)的人。
我相信这一点,这不是一个错误。
在Pocket PC上运行的小型应用程序中是如何发生的,在操作结束时,必须发出一个生成GUID的命令。 该命令在服务器上执行后,会被存储在服务器上的命令表中以及执行date。 有一天,当我debugging我发出了模块命令(与新生成的GUID附加),什么也没有发生。 我又做了一次(使用相同的GUID,因为GUID在操作开始时只产生一次),再次,也没有,最后试图找出命令没有执行的原因,我检查了命令表,和3周前插入的当前GUID相同。 不相信这一点,我从2周的备份中恢复了一个数据库,并在那里的指导。 检查了代码,新的guid是毫无疑问的。 鲍德冲撞,只发生过一次,但我真的希望我会赢得乐透反而,机会更大:)。
编辑:有一些因素可能会大大增加发生这种情况的机会,应用程序在PocketPC模拟器上运行,并且模拟器具有保存状态function,这意味着每次状态恢复时本地时间也恢复并guid是基于内部计时器….也紧凑框架的guid生成algorithm可能不如COM例如完整…
它们在理论上是可能的,但是用3.4E38个可能的数字,如果每年创build几十万亿的GUID,有一个重复的机会是0.00000000006( 来源 )。
如果两个用户结束了相同的GUID,我会打赌,在程序中有一个错误,导致数据被复制或共享。
首先让我们看看两个GUID碰撞的机会。 它不是像其他答案所说的那样,因为生日悖论中的1 ^ 2 ^ 128(10 ^ 38),这意味着两个GUID碰撞的几率为50%,实际上是2 ^ 64(10 ^ 19),这是一个很小的。 但是,这仍然是一个非常大的数字,因此假设您使用的GUID数量合理,碰撞概率很低。
还要注意,GUID不包含时间戳或MAC地址,因为很多人似乎也相信。 这对于v1的GUID是正确的,但是现在使用了v4的GUID,它们只是一个伪随机数 ,这意味着碰撞的可能性可以说是更高的,因为它们不再是时间和机器所独有的。
所以基本上答案是肯定的,碰撞是可能的。 但是他们不太可能。
编辑:固定说2 ^ 64
两个随机GUID碰撞的机会(10 ^ 38中的〜1)低于未检测到损坏的TCP / IP包(10 ^ 10中的〜1)的机会。 http://wwwse.inf.tu-dresden.de/data/courses/SE1/SE1-2004-lec12.pdf ,第11页。磁盘驱动器,CD驱动器等也是如此。
GUID在统计上是独一无二的,你从数据库中读取的数据在统计上是正确的。
请参阅维基百科的全球唯一标识符文章。 有几种方法来生成GUID。 显然,旧的(?)方式使用Mac地址,一个时间戳到一个非常短的单位和一个独特的计数器(以pipe理同一台计算机上的快速世代),所以使他们重复几乎是不可能的。 但是,这些GUID被丢弃,因为它们可以用来追踪用户…
我不确定微软使用的新algorithm(文章说可以预测一系列GUID,看起来他们不再使用时间戳了吗?上面链接的微软文章说了别的…)。
现在,GUID经过精心devise,名称上是全球唯一的,所以我将冒险是不可能的,或者是非常非常低的概率。 我会看别处。
在这种情况下,我认为奥卡姆razor是一个很好的指导。 你有一个GUID碰撞是不可能的。 更有可能你有一个错误,或有人搞乱你的数据。
两台具有MAC地址重复的以太网卡的Win95机器将在严格控制的条件下发出重复的GUIDS,特别是在build筑物中电源closures的情况下,以及它们同时启动时。
我知道人们喜欢GUID是神奇的并且保证是唯一的,但是实际上,大多数GUID只是121位随机数(在格式化时浪费了7位)。 如果你觉得使用一个很大的随机数字会感觉不舒服,那么使用一个GUID你应该感觉不舒服。
用来生成GUID的代码是否有一个bug? 是的,当然可以。 但是答案和编译器bug相同 – 你自己的代码更有可能是bug,所以先看看那里。
当然它可能….可能? 不太可能,但这是可能的。
请记住,同一台机器正在生成每个GUID(服务器),所以很多基于机器特定信息的“随机性”都会丢失。
只是咧嘴笑,尝试下面的脚本…(在SQL 2005上工作,不知道2000年左右)
declare @table table ( column1 uniqueidentifier default (newid()), column2 int, column3 datetime default (getdate()) ) declare @counter int set @counter = 1 while @counter <= 10000 begin insert into @table (column2) values (@counter) set @counter = @counter + 1 end select * from @table select * from @table t1 join @table t2 on t1.column1 = t2.column1 and t1.column2 != t2.column2
重复运行(不到一秒钟)会产生一个相当宽的范围,即使在极短的时间间隔内也是如此。 到目前为止,第二select还没有产生任何东西。
如果用户有不同的网卡机器,即使不是,它仍然是一个极端微乎其微的理论风险。
就个人而言,我会看看其他地方,因为它更可能是一个错误,而不是一个GUID冲突…
当然,你不要把GUID中的位删除,以缩短它的长度。
当然有可能,甚至可能。 这不像每个GUID都在可能的数字空间的随机部分。 在两个线程试图同时生成一个线程的情况下,禁止某种带有信号量的集中GUID函数,可能会得到相同的值。
我将以“我不是一个networking人物,所以我可以做出完全不相干的句子”作为序言。“
当我在伊利诺伊州立大学工作时,我们有两个戴尔台式机,在不同的时间订购。 我们把第一个放在networking上,但是当我们试图把第二个放到networking上时,我们开始接受疯狂的错误。 经过很多故障排除之后,确定两台机器都生产相同的GUID(我不确定究竟是什么原因,但是这使得它们都不能在networking上使用)。 戴尔实际上把两台机器换成了有缺陷
如果通过类似SQL Server中的NEWID()
函数生成GUID冲突(尽pipe当然可能,正如其他答案所强调的),那么很可能会遇到GUID冲突。 有一件事他们没有指出的是,如果你在浏览器上用JavaScript生成GUID,实际上很可能会碰到碰撞。 在不同的浏览器中,不仅存在RNG中的问题,而且还遇到了一些问题:Google蜘蛛似乎caching了这样的函数的结果,并最终将相同的GUID传递给我们的系统。
在这里看到各种答案的更多细节:
在JavaScript中生成UUID时的冲突?