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
作为软件开发人员,如果用户来找您并说“它不起作用”,您会怎么说?
乔什·乔丹

152
等待数万亿年。
滚刀

67
更新,因为这是我今天在网上看到的最有趣的事情。
jrockway

32
@jrockway-哈哈 我很难找到关于这个问题的根本上没有错的信息。我看得越久,它就会变得越有趣。
tylerl

243
它在全球范围内是唯一的,因此在我们的星球上也是唯一的。如果您想要一个真正唯一的ID,则需要使用一个通用的唯一ID(UUID)。我假设您只对我们宇宙中的独特性感兴趣。:-)
tvanfosson

Answers:


407

Kai,我提供了一个程序,该程序可以使用线程来完成您想做的事情。它是根据以下条款许可的:您必须为运行它的每个CPU内核每小时向我支付$ 0.0001。费用在每个日历月末支付。请尽快与我联系以获取我的Paypal帐户详细信息。

using System;
using System.Collections.Generic;
using System.Linq;

namespace GuidCollisionDetector
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reserveSomeRam = new byte[1024 * 1024 * 100];     // This indeed has no effect.

            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
            // Fill up memory with guids.
            var bigHeapOGuids = new HashSet<Guid>();
            try
            {
                do
                {
                    bigHeapOGuids.Add(Guid.NewGuid());
                } while (true);
            }
            catch (OutOfMemoryException)
            {
                // Release the ram we allocated up front.
                // Actually, these are pointless too.
                //GC.KeepAlive(reserveSomeRam);
                //GC.Collect();
            }
            Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());


            // Spool up some threads to keep checking if there's a match.
            // Keep running until the heat death of the universe.
            for (long k = 0; k < Int64.MaxValue; k++)
            {
                for (long j = 0; j < Int64.MaxValue; j++)
                {
                    Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
                    System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
                    {
                        if (bigHeapOGuids.Contains(Guid.NewGuid()))
                            throw new ApplicationException("Guids collided! Oh my gosh!");
                    }
                    );
                    Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
                }
            }
            Console.WriteLine("Umm... why hasn't the universe ended yet?");
        }
    }
}

PS:我想尝试一下Parallel扩展库。那很简单。

使用OutOfMemoryException作为控制流只是感觉不对。

编辑

好吧,看来这仍然吸引了选票。因此,我已经修复了GC.KeepAlive()问题。并将其更改为与C#4一起运行。

为了阐明我的支持条款:仅在2010年2月28日提供支持。请仅使用时间机器在当天发出支持请求。

编辑2 与往常一样,GC在管理内存方面比我做得更好。我自己以前做过的任何尝试都注定要失败。


120
最后一个Console.WriteLine让我发笑起来非常难。我认为您应该投掷一个CommonlyAcceptedCosmologicTheoriesWrongException
R. Martinho Fernandes 2009年

17
将其标记为“接受”还意味着@Kai接受@ligos规定的条款吗?
kb。

3
设置reserveSomeRam = null;实际上并没有完成任何事情。
DevinB,2010年

4
@devinb请解释一下?看起来它正在释放先前分配的字节,以便GC可以使用Collect()它。为什么它什么都没做?
神话

3
GuidCollisionDetector。这个名字有潜力
UfukHacıoğulları10年

226

这将运行多个小时。假设它以1 GHz循环(不会,它会慢得多),它将运行10790283070806014188970年。这是宇宙年龄的约830亿倍。

假设摩尔定律成立,那么不运行该程序,等待几百年,然后在数十亿倍的计算机上运行它,将会更快。实际上,如果您等到CPU速度提高并在运行之前购买新的CPU(除非您编写了这样的程序)后,任何运行时间比CPU速度加倍(大约18个月)的程序都将更快完成。可以暂停并在新硬件上恢复)。


27
该死的-所以也许服务器线程生成GUID是一个更好的主意?

107
四核处理器上的4个线程将使它运行在200亿倍于宇宙寿命的时间里-是的,这将有很大帮助。
rjmunro

34
我怀疑这是一个巨魔,但并非偶然:线程不是神奇的。如果您可以在一个线程上每秒执行十亿次操作,那么转到十个线程意味着每个线程运行的频率是原来的十分之一。每个线程每秒执行100 M次操作;每秒的操作总数没有增加。增加每秒操作数的方法是购买更多计算机。假设您又购买了十亿台计算机。这样可以将问题减少到仅花费10790283070806806年,这仍然超过四个小时。
Eric Lippert

10
我认为rjmunro假设每个线程都将在单独的内核上运行;830亿个宇宙/ 4个核心实际上大约等于200亿个宇宙。是时候购买英特尔股票了!
Dour High Arch

4
@Erik 830亿个处理器意味着您将能够在大约到目前为止宇宙存在的时间内完成该工作。因此,这还远远不够。
rjmunro

170

GUID理论上是不唯一的。这是您的证明:

  • GUID是128位数字
  • 如果不重新使用旧的GUID,则无法生成2 ^ 128 + 1或更多GUID

但是,如果将太阳的全部功率输出都用于执行此任务,则它在完成之前会变冷。

可以使用许多不同的策略来生成GUID,其中的一些策略采取特殊措施以确保给定的计算机不会两次生成相同的GUID。在特定算法中发现冲突将表明您生成GUID的特定方法是不好的,但通常不会证明任何有关GUID的信息。


44
鸽洞救援原理!
yfeldblum

22
+1为太阳变冷发表评论。关于256位以上的加密密钥毫无意义的地方,有一条有趣的评论。迭代所有可能的键值将花费比整个宇宙更多的能量。在CPU中切换一点需要少量能量(这就是产生热量的能量),当乘以2 ^ 256次时,这确实是一个非常庞大的数字,超过了存储在宇宙中的能量,使用E = mc2,宇宙将需要质量为2 ^ 227kg,我们的太阳是2 ^ 101kg,所以2 ^ 126个太阳!
Skizz

31
@Skizz:这仅适用于蛮力攻击。当加密方案被“破坏”时,这意味着可以用比暴力破解更少的时间来解决它,但是解决时间仍然与密钥大小成比例。
史蒂文·苏迪特

1
@StevenSudit:与密钥大小的指数成比例(除非P == NP)
Ihar Bury'2

1
@Orlangur与以位为单位的密钥大小成比例。
史蒂文·苏迪特

137

当然,GUID可能会发生冲突。由于GUID是128位,因此只需生成2^128 + 1它们并由鸽子孔原理,必须存在冲突。

但是,当我们说GUID是唯一的时,我们真正的意思是密钥空间太大,以至于几乎不可能偶然两次生成相同的GUID(假设我们是随机生成GUID)。

如果您n随机生成一系列GUID,则至少发生一次碰撞的可能性大约为p(n) = 1 - exp(-n^2 / 2 * 2^128)(这是生日问题,可能的生日数为2^128)。

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

为使这些数字具体化,2^60 = 1.15e+18。因此,如果您每秒生成十亿个GUID,则将花费36年的时间来生成2^60随机GUID,即使这样,发生碰撞的可能性仍然很高1.95e-03。在接下来的36年中,您更可能会在人生中的某个时刻谋杀4.76e-03)。祝好运。


239
如果您在人生中的某个时刻被谋杀,那很有可能会走到尽头。
迈克尔·迈尔斯

25
@mmyers:非常好。这意味着我现在被谋杀的可能性非常低,因为这还不是我生命的尽头。哦,等等...
Steven Sudit 2010年

同样,如果在短时间内创建了两个GUID,则它们在同一系统中使用的机会很小。因此,这增加了唯一性。
AMissico 2010年

这些数字和提及生日的问题毫无意义。GUID生成算法不会以相等的概率生成整个范围内的值。实际上,IIRC的原始算法使用了生成PC的MAC地址+当前时间作为结果的一部分-降低了与其他PC上生成的Guid发生冲突的风险,但当然减少了密钥空间。

17
您以为被谋杀的可能性对所有人类都是一个常数。但是很明显,在论坛帖子中发表sn亵言论的人是比普通人更容易被谋杀的人。
杰伊

61

如果您担心唯一性,可以随时购买新的GUID,以便丢弃旧的GUID。如果您愿意,我会在eBay上提出。


13
酷-整套从0到(2 ^ 128)-1多少钱?
Steve314,2009年

23
出售时,每1k GUID 0.01美元。如果您在接下来的60分钟内订购,我会送一些竹风铃。
ctacke

7
我的布景更独具一格,品质更高。他们经过了双重检查和验证,这使它们每个GUID值$ 1。如果您不想一次性进行全部投资,甚至可以分批购买。我将不得不每批额外收取10美元。
托马斯

3
我将为您设置月度计划,并以合理的价格为您提供无限的指导。^那些家伙正试图骗您,并向您出售价格过高的公团。我将向您出售中国制造的优质指南!
ErocM 2011年

47

我个人认为,“大爆炸”是由两个GUID碰撞引起的。


4
只需记住,这需要“特殊”的程序员来做...
AnthonyLambert 2011年

我想听听你对你的理论的推理。我认为我们可以以此为基础开展新宗教并招募T.Cruise!
ErocM 2011年

@ErocM; 请参见“ Brane宇宙论”(en.wikipedia.org/wiki/Brane_cosmology)和“膜(M-理论)”(en.wikipedia.org/wiki/Membrane_(M-理论)。这个想法是如果两个大脑接触一个新的宇宙。因此,您可以推断出,如果两个GUID接触,则会创建一个新的Universe。
2011年

2
如果Timecop教给我们的是,同一件事在任何给定时间都不能占据相同的空间。因此,如果两个GUID发生碰撞,它们将彼此消耗,并且由此产生的内爆将产生黑洞,吞噬整个宇宙。因此,实际上,它不会创建一个宇宙,而是会摧毁它。
AJC

42

您可以使用量子bogosort算法的变体在O(1)时间内证明这一点

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

21
调用Destroy()时出现异常。根据文字,我认为我的计算机缺少破坏当前宇宙的必要硬件。您知道我可以在哪里获得吗?
史蒂文·苏迪特

11
@Steven:不,有些管理人员太担心API对公众的外观有多糟糕,并指示它总是出于“安全原因”而失败。如果您查看方法的源代码,则只有一行:throw new MundaneHardwareException();。无论如何,我听说欧洲核子研究中心的家伙有某种大强子Thingy可以解决问题……
R. Martinho Fernandes 2010年

7
@Martinho:好的。我会考虑将替换Universe.Current.Destroy()Cern.Lhc.DestroyThisUniverse()
史蒂文·苏迪特

61
我知道我在Haskell编程是有原因的。这些副作用越来越可怕。
爱德华·KMETT

6
“有一种理论指出,如果任何人确切地发现了宇宙的意义以及它为什么在这里,它将立即消失,并被更加奇怪的莫名其妙的事物所取代。还有另一种理论指出,这已经发生了”。-道格拉斯·亚当斯(Douglas Adams),《银河系漫游指南》
Mike Pirnat 2010年

28

任何两个GUID很有可能是唯一的(不相等)。

请参阅此SO条目,以及来自Wikipedia

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

因此,可能您不得不等待更多的数十亿年,并且希望您知道我们即将灭亡的那一刻,才在宇宙之前发生。


那么2 ^ 128是否不是正确数量的Guid?

21
它是。您为什么认为2 ^ 128是个小数字?
jrockway

是的,正确的数量为2 ^ 128。
重力1998年

3
这真是个地狱。$ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev

45
@Infinity-甚至对你来说?
奥斯丁·理查森

27

[更新:] 正如以下评论所指出的那样,较新的MS GUID是V4,并且不将MAC地址用作GUID生成的一部分(不过,我还没有看到从MS获得V5实现的任何迹象,因此,如果有人拥有链接确认让我知道)。尽管使用V4,但是时间仍然是一个因素,并且复制GUID的几率仍然很小,以至于与任何实际使用无关。您肯定不可能仅从单个系统测试(如OP试图执行的操作)中生成重复的GUID。

这些答案大多数都缺少有关Microsoft GUID实施的要点。GUID的第一部分基于时间戳,另一部分基于网卡的MAC地址(如果未安装NIC,则为随机数)。

如果我正确理解这一点,则意味着复制GUID的唯一可靠方法是在MAC地址相同且两个系统的时钟在生成该时钟的确切时间的多台计算机上同时运行GUID生成发生(如果我正确理解的话,时间戳是基于毫秒的。。。)即使如此,数字中还有很多其他位是随机的,所以几率仍然很小。

出于所有实际目的,GUID是通用的。

“ The Old New Thing”博客对MS GUID进行了很好的描述


3
在使用虚拟化时,这实际上是可行的。您可以而且确实会得到重复的指导。
Goran

8
尽管Raymond在MAC地址部分已经过时,但是Microsoft不再使用它们。有关V1和V4指南之间的区别,请参见en.wikipedia.org/wiki/GUID#Algorithm
Michael Stum

1
这已不再是这种情况。当前的V5方案仅为128位纯伪随机性。
爱德华·KMETT

有趣的是,您如何陈述我比我晚一个月所做的所有事情,您得到16分,而我仍然有0分?
AnthonyLambert 2010年

1
Ya Tony,这有点奇怪。回到我回答帖子时,只有3或4个答案,我不记得看到你的了……如果有的话,我只是投票赞成。当已经有足够好的其他答案覆盖时,我通常不回答问题(这就是为什么我的总体代表可能偏低的原因)。
Stephen M. Redd

23

如果您想在代码中的许多地方检查GUID的唯一性,可以使用一种漂亮的扩展方法。

internal static class GuidExt
{
    public static bool IsUnique(this Guid guid)
    {
        while (guid != Guid.NewGuid())
        { }
        return false;
    }
}

要调用它,只需在生成新guid时调用Guid.IsUnique。

Guid g = Guid.NewGuid();
if (!g.IsUnique())
{
    throw new GuidIsNotUniqueException();
}

...哎呀,我什至建议您打电话两次,以确保它在第一轮中正确。


2
这如何确保this guid从未在世界上其他地方产生过?:p哎呀,我们需要一个世界Guid池。:)
nawfal 2012年

19

数到2 ^ 128-雄心勃勃。

让我们想象一下,我们每台计算机每秒可以计算2 ^ 32个ID-并不那么雄心勃勃,因为它甚至还没有达到每秒43亿个ID 。让2台32台计算机专用于该任务。此外,让我们获得2 ^ 32个文明来为任务分配相同的资源。

到目前为止,我们每秒可以计数2 ^ 96个ID,这意味着我们将计数2 ^ 32秒(略超过136年)。

现在,我们需要做的是为每台专用4,294,967,296台计算机分配4,294,967,296个文明,每台计算机每秒能够计数4,294,967,296个ID,这纯粹是在接下来的136年左右的时间里完成的-我建议我们现在就开始这项基本任务; -)


17

好吧,如果830亿年的运行时间没有吓到您,请认为您还需要将生成的GUID存储在某个地方,以检查是否有重复的GUID。存储2 ^ 128个16字节数字仅需要您预先分配4951760157141521099596496896 TB的RAM,因此,假设您有一台可以容纳所有这些内容的计算机,并且以某种方式找到了购买10 TB的TB DIMM的地方,它们将组合在一起。重达8个以上的地球质量,因此您甚至可以在按“运行”之前将其严重偏离当前轨道。三思!


12
for(begin; begin<end; begin)
    Console.WriteLine(System.Guid.NewGuid().ToString());

您没有增加,begin因此条件begin < end始终为真。


1
否-原因是我无法遍历bigint
Kai

3
他是永远循环还是循环340282366920938463463374374607431768211456次真的有关系吗?
杰伊

3
所以...您宁愿被打340282366920938463463374374607431768211456次还是永远!
ErocM 2011年

实际上,这才是问题的真正答案!也没有投票:p
nawfal 2012年


9

大概您有理由相信,产生Guid的算法并不是产生真正的随机数,而是实际上以周期<< 2 ^ 128循环。

例如用于导出GUID的RFC4122方法,该方法可修复某些位的值。

循环的证明将取决于时间段的可能大小。

对于小段时间,如果GUID不匹配(如果匹配则终止),则可以使用hash(GUID)-> GUID的哈希表在冲突时进行替换(如果匹配则终止)。还应考虑仅在随机时间内进行替换。

最终,如果两次碰撞之间的最大时间间隔足够大(并且事先未知),则任何方法都只会产生一个可能性,即如果存在该碰撞就会被发现。

请注意,如果生成Guid的方法基于时钟(请参阅RFC),则可能无法确定是否存在冲突,因为(a)您将无法等待足够长的时间以使时钟回绕,或(b)您无法在一个时钟滴答声中请求足够的Guid来强制碰撞。

或者,您可能能够显示Guid中位之间的统计关系,或Guid之间位的相关性。这种关系可能很可能导致算法有缺陷,而不必一定能够找到实际的冲突。

当然,如果您只想证明Guid可以碰撞,那么答案就是数学证明,而不是程序。


8

我不明白为什么没人会提到升级显卡...当然,如果您有高端的NVIDIA Quadro FX 4800或其他东西(192个CUDA内核),它将更快。

当然,如果你能买得起几NVIDIA Qadro Plex的2200个S4S(在960个CUDA核心每一个),这个计算将真正。也许NVIDIA会愿意借给您一些PR特技“技术演示”?

他们当然想成为这一历史性计算的一部分...


嗯.....我可以在工作的10,000节点网格上运行它。
AnthonyLambert

8

但是您是否必须确保有重复项,还是只在乎是否可以重复项。为确保您有两个人的生日相同,您需要366人(不计算counting年)。要让两个人有相同的生日的机会要多于50%,那么您只需要23个人。那是生日的问题

如果您有32位,则只需要77,163个值即可获得大于50%的重复机会。试试看:

Random baseRandom = new Random(0);

int DuplicateIntegerTest(int interations)
{
    Random r = new Random(baseRandom.Next());
    int[] ints = new int[interations];
    for (int i = 0; i < ints.Length; i++)
    {
        ints[i] = r.Next();
    }
    Array.Sort(ints);
    for (int i = 1; i < ints.Length; i++)
    {
        if (ints[i] == ints[i - 1])
            return 1;
    }
    return 0;
}

void DoTest()
{
    baseRandom = new Random(0);
    int count = 0;
    int duplicates = 0;
    for (int i = 0; i < 1000; i++)
    {
        count++;
        duplicates += DuplicateIntegerTest(77163);
    }
    Console.WriteLine("{0} iterations had {1} with duplicates", count, duplicates);
}

1000 iterations had 737 with duplicates

现在128位是很多,所以您仍然在谈论大量项目,仍然使您发生碰撞的机率降低。对于给定的赔率,您将需要使用以下记录数:

  • 8亿发生1/1000的碰撞机会
  • 217亿发生50%的碰撞机会
  • 396亿个发生碰撞的机率高达90%

每年大约发送1E14封电子邮件,因此在这个水平上大约需要400,000年的时间,您有90%的机会拥有两个具有相同GUID的机会,但这与说您需要运行830亿台计算机相比有很大不同倍于宇宙的年龄,或者太阳会在找到副本之前变冷。


7

你们不是都错过了重点吗?

我认为GUID是使用两种方法生成的,这使得它们在全球范围内具有独特性的可能性很高。一种是使用您所用计算机的MAC地址作为种子,而另一种则使用生成它们的时间加上一个随机数。

因此,除非您在实际的计算机上运行它,并且在计算机用来在GUID中表示时间的最短时间内运行所有猜测,否则无论您使用系统调用进行多少次猜测,都不会生成相同的数字。

我想如果您知道GUID的实际制作方法实际上会大大缩短猜测时间。

托尼


3
并非所有GUID都是以这种方式创建的。即使是这样,Kai也只需要等到用于创建GUID的时间戳回绕足够的时间,就可以再次使用他用于创建GUID的时间戳。
Dour High Arch

3
自2000年或2001年以来,指南就不再基于mac地址了。作为NT4和/或Win2k的Service Pack之一,他们完全改变了算法。现在,它们是由随机数生成器生成的,减去了几位标识它是什么类型的向导。
KristoferA

4
并非所有的GUID都来自Windows平台...
AnthonyLambert,2009年

OP提到C#,因此它是Windows。此外,V4 GUID是Windows专用的东西吗?
史蒂文·苏迪特

5
@Martinho:啊,但是GuidTest.cs中Mono对Guid的单元测试包含一个方法,该方法创建两个新的GUID并检查它们是否相等,如果它们相等则失败。随着Mono的成功构建,我们可以绝对确定其GUID是独一无二的!:-)
史蒂文·苏迪特

6

您可以哈希GUID。这样,您应该可以更快地得到结果。

哦,当然,同时运行多个线程也是一个好主意,这样一来,您将增加竞争条件在不同线程上两次生成相同GUID的机会。


6

GUID为124位,因为4位保存版本号。


不添加此评论的原因:没人提到它,我也不知道该告诉谁。:)
Behrooz

我做到了。在我写的一些“真实”应用程序中,我在一个约有26万行的表中遇到了Guid冲突。(MSSQL 2008 R2 Express)。
Behrooz

6
  1. 前往纽约市的低温实验室。
  2. 将自己冻结大约1990年。
  3. 在Planet Express找工作。
  4. 购买一个全新的CPU。建造一台计算机,运行该程序,然后使用伪永久运动机(如世界末日机器)将其放置在安全的地方。
  5. 等到发明时间机器。
  6. 使用时间机器跳到未来。如果您购买了1YHz 128位CPU,请转到3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 ps在开始运行程序后。
  7. ...?
  8. 利润!!!

... 10,783,127即使您拥有1YHz的CPU,至少要花费数年的时间1,000,000,000,000,000(或1,125,899,906,842,624您更喜欢使用二进制前缀)比1GHz CPU快几倍。

因此,与其等待计算结束,不如喂掉失去家园的鸽子,因为 n鸽子回家。:(

或者,您可以等到发明了128位量子计算机。然后,可以通过在合理的时间(可能是合理的时间)内使用程序来证明GUID不是唯一的。


我一直在等待这个答案的超级英雄参考-海报失败:p-仍然很棒。
IbrarMumtaz'2

4

您是否尝试begin = begin + new BigInteger((long)1)过替代begin ++?


2
没有人投票支持真正回答这个问题的答案:P
nawfal 2012年

4

如果生成的UUID数量遵循摩尔定律,那么在可预见的将来永不耗尽GUID的印象是错误的。

使用2 ^ 128个UUID,只需要18个月* Log2(2 ^ 128)〜= 192年,我们便用完了所有UUID。

而且我相信,自从大规模采用UUID以来的过去几年中(至今没有任何统计证据),我们生成UUID的速度正在以比摩尔定律更快的速度增长。换句话说,我们距离UUID危机的处理时间可能还不到192年,这比宇宙终结早了很多。

但是由于我们肯定不会在2012年底将它们耗尽,因此我们将其留给其他物种来担心这个问题。


3

GUID生成代码中错误的几率比生成冲突的算法的几率高得多。代码中测试GUID的错误的可能性更大。放弃。


2

该程序尽管有错误,但显示出GUID不是唯一的证明。那些试图证明相反的人则忽略了这一点。该陈述仅证明了某些GUID变体的执行不力。

根据定义,GUID不一定是唯一的,而根据定义它是高度唯一的。您只是修饰了高度的含义。取决于版本,实施者(MS或其他),VM的使用等,您对高度更改的定义。(请参阅先前文章中的链接)

您可以缩短128位表以证明您的观点。最好的解决方案是使用哈希公式来缩短带有重复项的表,然后在哈希冲突后使用完整值,并基于此值重新生成GUID。如果从不同的位置运行,则将哈希/完整密钥对存储在中央位置。

Ps:如果目标只是生成x个不同值,请创建此宽度的哈希表,然后检查哈希值。


2

不是在这里篝火晚会,但实际上确实发生了,是的,我了解您一直在给这个家伙开玩笑,但是GUID仅在原理上是唯一的,我碰到了这个线程,因为有一个错误在WP7仿真器中,这意味着每次启动时,它都会在首次​​调用时发出SAME GUID!因此,从理论上讲,您不会发生冲突,如果在生成上述GUI时出现问题,则可以获取重复项

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


1

由于部分Guid生成是基于当前机器的时间,因此我得到一个重复的Guid的理论是:

  1. 执行Windows的全新安装
  2. 创建一个启动脚本,以将时间重置为2010-01-01 12:00:00,就像Windows启动一样。
  3. 在启动脚本之后,它将触发您的应用程序生成Guid。
  4. 克隆此Windows安装,以便排除在后续启动中可能发生的任何细微差别。
  5. 使用该映像重新映像硬盘驱动器,然后启动计算机几次。

0

对我来说..单个内核生成UUIDv1所花费的时间保证了它是唯一的。即使在多核情况下,如果UUID生成器一次只允许为您的特定资源生成一个UUID(请记住,多个资源可以完全利用相同的UUID,但是不太可能,因为资源本质上是地址的一部分),那么您在时间戳记耗尽之前,将有足够多的UUID支持您。在这一点上,我真的怀疑您是否会在意。


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

证明GUID不唯一的唯一解决方案是拥有World GUID池。每次在某处生成GUID时,都应向组织注册。或许,我们可能包括一个标准化,所有GUID生成器都需要自动注册它,并且它需要有效的Internet连接!

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.