GUID不是唯一的简单证明

323

我想证明GUID在简单测试程序中不是唯一的。我原以为下面的代码会运行几个小时,但它没有工作。我该怎么让它工作?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

我正在使用C#。


107
作为一名软件开发者,如果用户向您反映“它不工作了”,您会怎么回答? - JoshJordan
152
等待数万亿年。 - hobbs
67
因为这是我今天在网上看到最有趣的事情,所以点了个赞。 - jrockway
32
@jrockway - 哈哈。我发现关于这个问题的任何信息都基本上是错误的,让我看得越久就越好笑。 - tylerl
243
它只是全局唯一的,因此它只在我们的星球上是唯一的。如果您想要一个真正唯一的ID,您需要使用全局唯一标识符(UUID)。我猜您只对我们的宇宙内的唯一性感兴趣。 :-) - tvanfosson
显示剩余24条评论
30个回答

6

GUID(全局唯一标识符)是124位,其中4位用于存储版本号。


不将此作为评论的原因是:没有人提到过,而我也不知道应该告诉谁。:) - Behrooz
太好了,我做到了。在我编写的某个“真实”应用程序中,我在一个有大约260k行的表中遇到了Guid冲突。(MSSQL 2008 R2 Express)。 - Behrooz

4

你尝试过使用 begin = begin + new BigInteger((long)1) 替代 begin++ 吗?


2
没有人投票给真正回答问题的答案 :P - nawfal

4
如果生成的UUID数量遵循摩尔定律,那么在可预见的未来永远不会用尽GUID的印象是错误的。有2 ^ 128个UUID,只需要18个月* Log2(2 ^ 128)〜192年,我们就会用完所有的UUID。我相信(没有任何统计证明),自从UUID被广泛采用以来的几年中,我们生成UUID的速度正在以比摩尔定律规定更快的速度增长。换句话说,我们可能在不到192年的时间内就必须处理UUID危机,这比宇宙终结的时间要早得多。但是既然我们肯定不会在2012年底之前用完它们,我们将把这个问题留给其他物种来担心。

3

生成GUID的代码中存在bug的可能性远高于算法生成冲突的可能性。而你编写测试GUID的代码中出现bug的概率更大。放弃吧。


2
尽管该程序存在错误,但它证明了GUID并非唯一。试图证明相反的人没有抓住重点。这个声明只证明了某些GUID变体实现的薄弱性。
根据定义,GUID并非必须唯一,但高度唯一。你只是精确了高度的含义。根据版本、实现者(MS或其他)、VM的使用等因素,高度的定义会有所不同。(请参见先前帖子中的链接)
你可以缩短你的128位表以证明你的观点。最好的解决方案是使用哈希公式来缩短具有重复项的表,然后在哈希冲突发生时使用完整值,并基于此重新生成GUID。如果从不同位置运行,你将在一个中央位置存储哈希/完整键对。
附:如果目标只是生成x个不同的值,请创建这个宽度的哈希表,并检查哈希值。

2

不是要泼冷水,但实际上这种情况确实存在。我知道你们一直在开玩笑,但 GUID 只是理论上独一无二的。我之所以进入这个帖子,是因为 WP7 模拟器中有一个 bug,每次启动时都会在第一次调用时输出相同的 GUID!因此,在理论上虽然不可能发生冲突,但如果生成 GUID 时出现问题,就可能会出现重复。

http://forums.create.msdn.com/forums/p/92086/597310.aspx#597310


1

由于 Guid 的一部分是基于当前机器的时间生成的,我认为获取重复的 Guid 的方法如下:

  1. 进行干净的 Windows 安装
  2. 创建一个启动脚本,在 Windows 启动时将时间重置为 2010-01-01 12:00:00。
  3. 在启动脚本之后,触发您的应用程序生成一个 Guid。
  4. 克隆此 Windows 安装,以排除后续启动中可能发生的任何微妙差异。
  5. 使用此映像重新映像硬盘并启动机器多次。

0

这里也有一个解决方案:

int main()
{
  QUuid uuid;
  while ( (uuid = QUuid::createUuid()) != QUuid::createUuid() ) { }
  std::cout << "Aha! I've found one! " << qPrintable( uuid.toString() ) << std::endl;
}

注意:需要Qt,但我保证如果你让它运行足够长的时间,它可能会找到一个。

(注释注释:实际上,现在我看着它,可能有一些关于生成算法的东西防止两个后续生成的uuid发生碰撞 - 但我有点怀疑)。


0
对于我而言,单核生成UUIDv1所需的时间可以保证其唯一性。即使在多核情况下,如果UUID生成器只允许为您特定的资源一次生成一个UUID(请记住,多个资源完全可以使用相同的UUID,但是这种情况很少见,因为资源固有地属于地址的一部分),那么您将拥有足够多的UUID可用于直到时间戳耗尽。到那时,我真的不认为您会关心。

0
唯一证明GUID不唯一的解决方案是建立一个全球GUID池。每次在某处生成一个GUID,都应该将其注册到组织中。或者说,我们可以包括一个标准化要求,即所有GUID生成器都需要自动注册,并且为此需要保持活动的互联网连接!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接