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 2009年

152
数兆年待ってください。
ホッブズ

67
これは私が今日オンラインで見た中で最も面白いものだからです。
jrockway 2009年

32
@jrockway-笑 この質問について、根本的に間違っていないものを見つけるのに苦労しています。長く見れば見るほどおかしくなります。
tylerl 2009年

243
それは世界で唯一のものであるため、私たちの惑星では唯一のものです。本当にユニークなIDが必要な場合は、ユニバーサルユニークID(UUID)を使用する必要があります。あなたは私たちの宇宙の中の唯一性にのみ興味があると思います。:-)
tvanfosson 2009年

回答:


407

カイ、私はあなたがスレッドを使ってあなたが望むことをするプログラムを提供しました。これは、次の条件でライセンスされています。実行するCPUコアごとに1時間あたり$ 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:Parallel extensionsライブラリを試してみたかった。それは簡単でした。

そして、制御フローとしてOutOfMemoryExceptionを使用すると、間違っているように感じます。

編集

まあ、これはまだ投票を集めているようです。そこで、GC.KeepAlive()の問題を修正しました。そして、C#4で実行するように変更しました。

そして、私のサポート条件を明確にするために:サポートは2010年2月28日でのみ利用可能です。タイムマシンで当日のみサポートをお願いします。

編集2 いつものように、GCはメモリの管理で私よりも優れています。それを自分でやろうとした以前の試みは失敗する運命にありました。


120
その最後のConsole.WriteLineは、私を本当に笑わせました。CommonlyAcceptedCosmologicTheoriesWrongException代わりに投げるべきだと思います。
R.マルティーニョフェルナンデス

17
これをAcceptedとマークすることは、@ Kaiが@ligosで規定された条件を受け入れることも意味しますか?
kb。

3
設定reserveSomeRam = null;は実際には何も行いません。
DevinB

4
@devinbは説明してください?以前に割り当てられたバイトを解放して、GCが解放できるように見えますCollect()。なぜ何も達成しないのですか?
神話2010年

3
GuidCollisionDetector。名前に可能性がある
UfukHacıoğulları2010

226

これは何時間も実行されます。1 GHzでループする(そうならない-それよりもはるかに遅い)と仮定すると、10790283070806014188970年間動作します。これは宇宙の時代の約830億倍長いです。

ムーアの法則が成立すると仮定すると、このプログラムを実行せずに数百年待って、何十億倍も速いコンピューターで実行するほうがはるかに速くなります。実際、CPU速度が2倍になる(約18か月)よりも実行に時間がかかるプログラムは、CPU速度が上がるまで待ってから新しいCPUを購入してから実行すると、完了までの時間が短くなります。新しいハードウェアで一時停止および再開できます)。


27
いまいましい-おそらくGUIDを生成するサーバースレッドはより良いアイデアですか?
カイ

107
クアッドコアプロセッサで4つのスレッドを実行すると、宇宙の時代の200億倍の速度で実行できます。そうすれば、それは大きな助けになります。
rjmunro

34
私はこれがトロールであることを疑っていますが、偶然ではありません。スレッドは魔法ではありません。1つのスレッドで1秒あたり10億の操作を実行できる場合、10のスレッドに進むと、各スレッドが1/10の頻度で実行されます。各スレッドは1秒あたり100 Mの操作を実行します。1秒あたりの操作の総数は増加しません。1秒あたりの操作数を増やす方法は、より多くのコンピューターを購入することです。10億台以上のコンピューターを購入したとします。これにより、問題は10790283070806年(4時間以上)に短縮されます。
Eric Lippert、

10
rjmunroは、各スレッドが個別のコアで実行されると想定しています。830億のユニバース/ 4コアは、実際には約200億のユニバースに相当します。インテル株を買う時がきた!
Dour High Arch、

4
@Erik 830億プロセッサーは、宇宙がこれまでに存在していた時間とほぼ同じ時間でそれを実行できることを意味します。ですからそれでも十分ではありません。
rjmunro 2009年

170

GUIDは理論的には一意ではありません。ここにあなたの証拠があります:

  • GUIDは128ビットの数値です
  • 古いGUIDを再利用せずに2 ^ 128 + 1以上のGUIDを生成することはできません

ただし、太陽の出力全体がこのタスクの実行に向けられている場合は、完了する前に冷たくなります。

GUIDは、いくつかの異なる手法を使用して生成できます。その一部は、特定のマシンが同じGUIDを2回生成しないことを保証するために特別な措置をとります。特定のアルゴリズムで衝突を検出すると、GUIDを生成するための特定の方法が不適切であることが示されますが、GUIDについては一般的に何も証明されません。


44
救助への鳩の穴原理!
yfeldblum 2009年

22
太陽が寒くなるコメント+1。256ビットを超える暗号化キーの無意味さについて、興味深いコメントがどこかにありました。可能なすべてのキー値を反復処理するには、宇宙全体が保持するよりも多くのエネルギーが必要になります。CPUでビットを切り替えるには少量のエネルギーが必要です(これにより熱が発生します)。これは、2 ^ 256倍すると、宇宙に保存されているエネルギーを超える非常に大きな数であり、E = mc2を使用すると宇宙に大量のエネルギーが必要になります2 ^ 227kg、太陽は2 ^ 101kgなので、2 ^ 126太陽です!
Skizz、

31
@Skizz:これはブルートフォース攻撃にのみ当てはまります。暗号化スキームが「壊れている」場合、それはブルートフォースよりも短い時間で解決できることを意味しますが、解決時間はキーサイズに比例したままです。
Steven Sudit、

1
@StevenSudit:鍵サイズの指数に比例(P == NPを除く)
Ihar Bury

1
@Orlangurビット単位で測定されたキーサイズに比例します。
Steven Sudit

137

もちろん、GUIDは衝突する可能性があります。GUIDは128ビットなので2^128 + 1、それらを生成し、鳩の巣の原理で衝突が発生するはずです。

ただし、GUIDが一意であると言う場合、実際に意味するのは、キースペースが非常に大きいため、誤って同じGUIDを2回生成することは事実上不可能であるということです(GUIDをランダムに生成していると仮定します)。

nGUIDのシーケンスをランダムに生成する場合、少なくとも1つの衝突の可能性はおよそです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。したがって、毎秒10億のGUIDを生成する場合、2^60ランダムなGUID を生成するのに36年かかり、それでも衝突が発生する確率は変わりません1.95e-03。次の36年間で衝突を見つけるよりも、人生のある時点で殺される可能性が高くなります4.76e-03)。幸運を。


239
あなたが人生のある時点で殺害された場合、確率はそれが終わりになるでしょう。
マイケルマイヤーズ

25
@mmyers:すばらしい点。つまり、これが私の人生の終わりではないので、今殺されている私の可能性はばかげて低いです。ああ、待って...
Steven Sudit、

また、2つのGUIDが短期間で作成される場合、それらが同じシステム内で使用される可能性はわずかです。したがって、これにより一意性が向上します。
AMissico

これらの数字と誕生日の問題への参照は意味がありません。GUID生成アルゴリズムは、範囲全体にわたって同じ確率で値を生成しません。実際、IIRCの元のアルゴリズムは、生成するPCのMACアドレス+結果の一部として現在時刻を使用していました。これにより、他のPCで生成されたGuidとの衝突のリスクが軽減されますが、もちろんキースペースは削減されます。
Joe

17
あなたは、殺される確率はすべての人間にとって一定であると仮定しています。しかし明らかに、フォーラムの投稿に悪口を言う人は、平均的な人よりも殺害される可能性が高い種類の人々です。
ジェイ

61

一意性が心配な場合は、常に新しいGUIDを購入して、古いGUIDを捨てることができます。よろしければ、eBayに出品します。


13
Cool-0から(2 ^ 128)-1までの完全なセットの量は?
Steve314 2009年

23
販売中、1,000 GUIDあたり$ 0.01。次の60分で注文したら、私はいくつかの竹の風鈴を投げます。
09年

7
私のセットはより限定的で高品質です。それらは再確認され、検証されるため、GUIDごとに1ドルの価値があります。一度にすべての投資をしたくない場合は、バッチで購入することもできます。ただし、バッチごとにさらに$ 10を請求する必要があります。
トーマス

3
月額プランを設定し、適切な価格で無制限のガイドを提供します。^それらの人たちはあなたを詐欺してあなたに高値のギドを売ろうとしています。中国製の良質なGUIDを販売します!
ErocM 2011年

47

個人的には、2つのGUIDが衝突したときに「ビッグバン」が発生したと思います。


4
それを行うには、「特別な」種類のプログラマが必要です...
AnthonyLambert

あなたの理論に対するあなたの推論を聞きたいのですが。これに基づいて新しい宗教を開始し、T.Cruiseを採用できると思います。
ErocM 2011年

@ErocM; 「ブレーン宇宙論」(en.wikipedia.org/wiki/Brane_cosmology)および「メンブレン(M-Theory)」(en.wikipedia.org/wiki/Membrane_(M-Theory))を参照してください。アイデアは、2つのブレーンが接触すると、新しい宇宙が作成されます。したがって、2つのGUIDが接触すると、新しいユニバースが作成されると推測できます。
AMissico

2
Timecopが私たちに何かを教えてくれたなら、同じ問題がいつでも同じ空間を占めることはできないということです。したがって、2つのGUIDが衝突する場合、それらは互いに消費し、結果として生じる爆破はブラックホールを生成し、宇宙全体を乱食します。したがって、実際には、それは宇宙を作成することはなく、破壊するでしょう。
AJC

42

量子ボゴソートアルゴリズムのバリアントを使用して、O(1)時間でそれを示すことができます。

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

21
Destroy()を呼び出すと、例外が発生します。テキストに基づいて、私のコンピューターには現在の宇宙を破壊するために必要なハードウェアが不足していると思います。どこで入手できるか知っていますか?
Steven Sudit、

11
@Steven:いや、何人かの管理職はそのAPIがどれほどひどく見えるか心配しすぎて、「セキュリティ上の理由」で常に失敗するように指示しました。メソッドのソースを見ると、次の1行しかありませんthrow new MundaneHardwareException();。とにかく、私はCERNの人がトリックを行う可能性がありますビッグハドロンThingyのいくつかの種類の...持って聞いた
R.マルティーニ・フェルナンデス

7
@Martinho:ああ、そうか。私は交換に見ていきますUniverse.Current.Destroy()Cern.Lhc.DestroyThisUniverse()
Steven Sudit、

61
Haskellでプログラミングした理由があることは知っていました。これらの副作用は恐ろしくなっています。
エドワードKMETT 2010年

6
「誰もが宇宙が何のためにあるかを正確に発見し、それがなぜここにあるのかを発見した場合、それは即座に消え、さらに奇妙に不可解なものに置き換えられると述べている理論があります。これはすでに起こったと述べている別の理論があります。 」-ダグラスアダムス、銀河へのヒッチハイカーのガイド
マイクピルナット

28

任意の2つのGUIDが一意である可能性が非常に高い(等しくない)。

このSOエントリ、およびWikipediaを参照してください

生成された各GUIDが一意であるとは限りませんが、一意のキーの総数(2 ^ 128または3.4×10 ^ 38)は非常に多いため、同じ番号が2回生成される確率は非常に小さくなります。たとえば、約5×10 ^ 22の星を含む観測可能な宇宙を考えてみましょう。すべてのスターは6.8×10 ^ 15の普遍的に一意のGUIDを持つことができます。

したがって、おそらく何十億年も待つ必要があり、宇宙が終わる前に宇宙に到達することを願っています。


では、2 ^ 128は可能なGUIDの正しい数ではありませんか?
カイ

21
そうです。なぜ2 ^ 128は小さい数だと思いますか?
jrockway 2009年

はい、2 ^ 128は可能なGUIDの正しい数です。
Graviton

3
それは数の地獄です。$ irb >> 2**128 => 340282366920938463463374607431768211456
adamJLev 2010年

45
@Infinity-あなたにも?
オースティンリチャードソン

27

[更新:] 以下のコメントが指摘するように、新しいMS GUIDはV4であり、GUID生成の一部としてMACアドレスを使用しません(ただし、MSからのV5実装の兆候は見たことがありません。リンクを確認してください)。ただし、V4を使用しても、時間は依然として重要な要素であり、GUIDの重複に対する確率は非常に小さいため、実際の使用には関係ありません。OPが実行しようとしたような単一のシステムテストから重複したGUIDを生成することはおそらくありません。

これらの回答のほとんどには、MicrosoftのGUID実装に関する重要な点が1つありません。GUIDの最初の部分はタイムスタンプに基づいており、別の部分はネットワークカードのMACアドレス(またはNICがインストールされていない場合は乱数)に基づいています。

これを正しく理解していれば、GUIDを複製する唯一の信頼できる方法は、MACアドレスが同じで、両方のシステムのクロックが生成時に同じ時刻であった複数のマシンで同時にGUID生成を実行することであることを意味します発生しました(タイムスタンプは、正しく理解していればミリ秒に基づいています)...それでも、ランダムな数のビットが他にもたくさんあるので、オッズはまだほとんどありません。

すべての実用的な目的で、GUIDは普遍的に一意です。

"The Old New Thing"ブログには、MS GUIDに関するかなり良い説明があります。


3
これは、仮想化を使用すると実際に実行できます。できますし、重複したGUIDを取得します。
ゴラン、

8
RaymondはMACアドレスの部分が古くなっていますが、Microsoftではこれらを使用していません。V1とV4のGuidの違いについては、en.wikipedia.org / wiki / GUID#Algorithmを参照してください。
Michael Stum

1
これはもう当てはまりません。現在のV5スキームは、128ビットの純粋な疑似ランダムの良さです。
エドワードKMETT 2010年

おかしいですが、私より1か月遅れてすべてのことを言って、16ポイントを獲得しても、まだ0のままですか?
AnthonyLambert

1
トニーさん、これには奇妙な点があります。投稿に答えたとき、3つまたは4つの回答しかなかったので、あなたの回答を見たことを覚えていませんでした。他の回答がすでに十分カバーしている場合、私は通常、質問に答えません(そのため、全体的な担当者はかなり低いと思われます)。
スティーブンM.レッド

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回呼び出すことをお勧めします。


2
これthis guidは、この世界の他のどこにも生成されていないことをどのように保証しますか?:pヘックワールドGUIDプールが必要です。:)
nawfal 2012

19

2 ^ 128に数えます-野心的です。

ではない-私たちはマシンごとに毎秒2 ^ 32のIDを数えることができることを想像することができますことを野心的な、それは毎秒さえ43億ではないからです。そのタスクに2 ^ 32マシンを割り当てましょう。さらに、それぞれに2 ^ 32の文明を取得して、同じリソースをタスクに割り当てます。

これまでのところ、1秒あたり2 ^ 96のIDをカウントできます。つまり、2 ^ 32秒(136年を少し超える)をカウントすることになります。

ここで必要なのは、4,294,967,296の文明を各専用の4,294,967,296のマシンに取得することだけです。各マシンは、毎秒4,294,967,296のIDをカウントすることができ、純粋に次の136年間このタスクを実行できます。この重要なタスクを今すぐ始めることをお勧めします。 -)


17

830億年の実行時間が怖くない場合は、生成されたGUIDをどこかに保存して、重複がないかどうかを確認する必要があると考えてください。2 ^ 128の16バイトの数値を保存する場合は、事前に4951760157141521099596496896テラバイトのRAMを割り当てるだけでよいので、それらすべてに対応できるコンピュータがあり、テラバイトのDIMMをそれぞれ10グラムで購入する場所を見つけたら、それらを合計すると地球の質量が8を超えるため、「実行」を押す前に、現在の軌道から真剣にシフトすることができます。考え直してください!


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

あなたはインクリメントしていないbeginので、条件begin < endは常に真です。


1
いいえ-原因私は反復BIGINTできない
カイ

3
彼が永遠にループするか、340282366920938463463374607431768211456回ループするかどうかは本当に重要ですか?
ジェイ

3
そう...あなたはむしろ340282366920938463463374607431768211456回または永遠にパンチされますか?!!?!?
ErocM

これが実際に質問に対する答えです。そして投票はまったくありません:p
nawfal


9

おそらく、Guidsを生成するアルゴリズムが真に乱数を生成するのではなく、実際に<< 2 ^ 128の周期で循環していると信じる理由があると思います。

たとえば、一部のビットの値を修正するGUIDを導出するために使用されるRFC4122メソッド。

サイクリングの証拠は、期間の可能なサイズによって異なります。

短い期間の場合、hash(GUID)のハッシュテーブル-> GUIDが一致しない場合に衝突時に置き換えられるGUID(一致する場合は終了する)のアプローチが考えられます。また、ランダムな時間の交換のみを行うことも検討してください。

最終的に、衝突の最大期間が十分に長い場合(事前にわかっていない場合)、どの方法でも、衝突が存在した場合に衝突が見つかる可能性があります。

GUIDの生成方法がクロックベースの場合(RFCを参照)、衝突が存在するかどうかを判断できない場合があることに注意してください。または(b)クロックティック内で衝突を強制するのに十分なGUIDを要求できない。

あるいは、Guid内のビット間の統計的関係、またはGuid間のビットの相関を示すことができる場合があります。このような関係により、実際の衝突を見つけることができない場合でも、アルゴリズムに欠陥がある可能性が高くなります。

もちろん、Guidsが衝突する可能性があることを証明したいだけなら、プログラムではなく数学的証明が答えです。


8

グラフィックカードのアップグレードについて誰も言及しなかった理由がわかりません...確かにハイエンドのNVIDIA Quadro FX 4800か何か(192 CUDAコア)を手に入れたら、これはもっと速くなるでしょう...

もちろん、NVIDIA Qadro Plex 2200 S4を(それぞれ960 CUDAコアで)数台購入できる場合、この計算は実際にます。おそらく、NVIDIAは、PRスタントとして「テクノロジーデモンストレーション」のためにいくつかを貸してくれるでしょうか?

きっと彼らはこれに参加したいと思うでしょう 歴史的な計算の ...


hmmmm .....職場の10,000ノードグリッドで実行できました。
AnthonyLambert 2010

8

しかし、あなたはあなたがあなたが複製を持っていることを確認する必要がありますか、それともそこにある場合にのみ気にしますかする可能性がある同じ誕生日の人が2人いることを確認するには、366人(うるう年を除く)が必要です。2人が同じ誕生日を迎える可能性が50%を超える場合、必要なのは23人だけです。それが誕生日の問題ですです。

32ビットの場合、重複の可能性が50%を超えるのに必要な値は77,163のみです。やってみよう:

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ビットはたくさんあります、それであなたはまだあなたに衝突の低い可能性をまだ与えている多くのアイテムを話している。概算を使用して、指定されたオッズに対して次の数のレコードが必要になります。

  • 衝突が発生する1/1000の確率で8億
  • 衝突が発生する確率が50%の場合、217億
  • 衝突が発生する確率が90%の場合は396億

毎年約1E14の電子メールが送信されるため、同じレベルのGUIDを2つ持つ確率が90%になる前に、このレベルでは約400,000年になります。宇宙の時代の何倍か、または複製が見つかる前に太陽が冷えてしまうこと。


7

あなた方全員が重要なポイントを見逃していませんか?

GUIDは2つのものを使用して生成されたため、グローバルに一意である可能性が非常に高くなると思いました。1つは、使用しているマシンのMACアドレスがシードされ、2つは生成された時間と乱数を使用することです。

したがって、実際のマシンでそれを実行し、マシンがGUIDで時間を表すために使用する最小時間内にすべての推測を実行しない限り、システムコールを使用して何回推測しても、同じ数は生成されません。

実際にGUIDを作成する方法を知っていると、推測にかかる時間が大幅に短縮されると思います。

トニー


3
すべてのGUIDがこの方法で作成されるわけではありません。それらがそうであったとしても、Kaiは、GUIDの作成に使用されたタイムスタンプが、GUIDの作成に使用されたタイムスタンプが再び使用されるのに十分な回数ラップするまで待つだけで済みます。
Dour High Arch、

3
2000年または2001年以降、GuidはMACアドレスに基づいていません。NT4またはWin2k、あるいはその両方のサービスパックの1つでは、アルゴリズムを完全に変更しました。それらは現在、乱数ジェネレータによって生成されますが、それがどの種類のGUIDであるかを識別する数ビットを除いたものです。
KristoferA

4
すべてのGUIDがWindowsプラットフォームから
取得さ

OPはC#について言及しているため、Windowsです。さらに、V4 GUIDはWindows専用のものですか?
Steven Sudit、

5
@Martinho:ああ、でもGuidTest.csのMonoのGuidの単体テストには、2つの新しいGUIDを作成してそれらが等しいかどうかをチェックし、等しい場合は失敗するメソッドが含まれています。Monoが正常にビルドされると、GUIDが一意であることが確実になります。:-)
Steven Sudit、

6

GUIDをハッシュできます。そうすれば、はるかに速く結果が得られるはずです。

もちろん、複数のスレッドを同時に実行することもお勧めです。これにより、異なるスレッドで同じGUIDが2回生成されて競合状態が発生する可能性が高まります。


6

4ビットはバージョン番号を保持するため、GUIDは124ビットです。


これをコメントとして追加しない理由:誰もそれを言及しておらず、誰にこれを伝えればよいのか分かりません。:)
Behrooz

Hooooraaaay私はそれをやった。私が書いたいくつかの「本当の」アプリで、私は約260k行のテーブルでGuidの衝突を得た。(MSSQL 2008 R2 Express)。
Behrooz、2012

6
  1. ニューヨーク市の極低温研究所に行きます。
  2. (大体)1990年間フリーズします。
  3. Planet Expressに就職しましょう。
  4. 新品のCPUを購入します。コンピューターを構築し、プログラムを実行し、終末機のような疑似永久運動機で安全な場所に置きます。
  5. タイムマシンが発明されるまで待ちます。
  6. タイムマシンを使用して未来にジャンプします。1YHz 128bit CPUを購入した場合は、3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 psた場合は、プログラムの実行を開始した後にます。
  7. ...?
  8. 利益!!!

... 10,783,127CPUが1YHzの場合でも、少なくとも数年はかかります1,000,000,000,000,000(または1,125,899,906,842,624バイナリプレフィックスを使用したい場合)、1GHz CPUよりも高速であるます。

ですから、コンピューティングが完了するのを待つよりも、家を失ったハトに餌をあげた方がいいでしょう。 nハトが。:(

または、128ビットの量子コンピューターが発明されるまで待つこともできます。次に、妥当な時間内にプログラムを使用することにより、GUIDが一意でないことを証明できます(たぶん)。


私はこの回答でスーパーヒーローの参照を待っていました-ポスターで失敗:p-それでも素晴らしいです。
IbrarMumtaz

4

begin = begin + new BigInteger((long)1)begin ++の代わりに試しましたか?


2
質問に本当に答える答えに投票した人はいません:P
nawfal

4

生成されるUUIDの数がムーアの法則に従う場合、予見可能な将来にGUIDが不足しないという印象は誤りです。

2 ^ 128 UUIDの場合、すべてのUUIDが不足するまでに18か月* Log2(2 ^ 128)〜= 192年しかかかりません。

そして、UUIDが大量に採用されてからの過去数年の間に(統計的証拠はまったくありませんが)、ムーアの法則よりもUUIDの生成速度が速くなっていると思います。言い換えると、UUID危機に対処する必要があるまで、おそらく192年未満です。それは、宇宙の終わりよりはるかに早いです。

しかし、2012年末までに枯渇することは絶対にないので、問題を心配するために他の種に任せます。


3

GUID生成コードのバグの確率は、衝突を生成するアルゴリズムの確率よりもはるかに高いです。GUIDをテストするコードのバグの可能性はさらに高くなります。あきらめる。


2

プログラムは、エラーではありますが、GUIDが一意ではないことの証拠を示しています。反対を証明しようとする人々は要点を逃しています。このステートメントは、GUIDバリエーションの一部の弱い実装を証明するだけです。

GUIDは、定義によって一意である必要はありません。定義によって高度に一意です。あなたは非常に意味を洗練させました。バージョン、実装者(MSなど)、VMの使用などに応じて、定義が大きく変わります。(以前の投稿のリンクを参照)

あなたのポイントを証明するために128ビットのテーブルを短くすることができます。最良の解決策は、ハッシュ式を使用して重複するテーブルを短くし、ハッシュが衝突してGUIDを再生成したら、完全な値を使用することです。別の場所から実行している場合は、ハッシュ/フルキーのペアを中央の場所に保存します。

Ps:x個の異なる値を生成するだけの場合は、この幅のハッシュテーブルを作成し、ハッシュ値を確認します。


2

ここで焚き火をしているわけではありませんが、実際に起こります、そして、はい、あなたがこの男に与えている冗談を理解しましたが、GUIDは原則的に一意であり、バグがあるため、このスレッドにぶつかりましたWP7エミュレータでは、起動するたびに最初に呼び出されたときに同じGUIDが表示されます!したがって、理論的には競合が発生しない場合、前述のGUIの生成に問題があると、重複が発生する可能性があります。

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

私にとって、単一のコアがUUIDv1を生成するのにかかる時間は、それが一意であることを保証します。マルチコアの状況でも、UUIDジェネレーターが特定のリソースに対して一度に1つの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が必要ですが、十分に長く実行すると、Qtが見つかるかもしれません。

(注:実際、私がそれを見ている今、生成アルゴリズムについて、後で生成される2つのuuidが衝突するのを防ぐ何かがあるかもしれませんが、ちょっと疑わしいです)。


0

GUIDが一意でないことを証明する唯一の解決策は、ワールドGUIDプールを持つことです。GUIDがどこかで生成されるたびに、組織に登録する必要があります。あるいは、すべてのGUIDジェネレータがそれを自動的に登録する必要があり、そのためにアクティブなインターネット接続が必要であるという標準化を含めるかもしれません!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.