小编典典

GUID 不唯一的简单证明

all

我想证明 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#。


阅读 69

收藏
2022-04-12

共1个答案

小编典典

Kai,我提供了一个程序,可以使用线程执行您想要的操作。它根据以下条款获得许可:您必须向我运行它的每个 CPU 内核每小时支付 0.0001
美元。费用应在每个日历月末支付。请尽快与我联系以获取我的贝宝帐户详细信息。

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:我想试试并行扩展库。那很简单。

并且使用 OutOfMemoryException 作为控制流感觉不对。

编辑

好吧,这似乎仍然吸引了选票。所以我已经修复了 GC.KeepAlive() 问题。并将其更改为使用 C# 4 运行。

并澄清我的支持条款:支持仅在 2010 年 2 月 28 日可用。请仅在当天使用时间机器提出支持请求。

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

2022-04-12