GUIDの衝突は可能ですか?


128

関連付けられているアプリを使用する各ユーザーのGUIDを使用するSQL Server 2000のデータベースで作業しています。どういうわけか、2人のユーザーが同じGUIDになってしまいました。Microsoftがアルゴリズムを使用して、衝突を引き起こす可能性が非常に低いランダムなGUIDを生成することを知っていますが、衝突はまだ可能ですか?


11
誰もが間違っていると言っています。1つのUniqueIdentifierが50万レコード未満のデータセットと衝突しました
。MSSQL2008

2
@Behrooz Yikes。私たちの友人の誕生日パラドックスのおかげでそれは不可能ではありませんが、完全にランダムなv4 GUIDを使用しても、それはまだめちゃくちゃ不運です。おそらく、より弱いGUID生成戦略を使用していましたか?
クレイグリンガー

6
@Behroozうわー。それは衝撃的な運です。
クレイグリンガー、

6
@Behroozこれは、おそらくMSSQLで使用されている欠陥のある疑似乱数です(ソフトウェアの品質を考えれば、ジェネレーターなどに32ビットのシードが含まれていても驚くことはありません)。数学は嘘をつかない。この可能性は非常に小さいので、MSSQL GUIDジェネレーターに欠陥がある(またはGUIDを生成するために使用される疑似ランダムジェネレーターである)可能性があります。
Alex

2
この時点で、質問と選択した回答の両方に128のスコアがあることを気に入ってください。一致?🤔
カイオ・クーニャ

回答:


127

基本的にはありません。私は誰かがあなたのデータベースをいじくり回したと思います。使用しているバージョンGUIDに応じて、値は一意(バージョン1 GUIDなど)または一意であり、予測不可能(バージョン4 GUIDなど)です。NEWID()関数のSQL Serverの実装では、128ビットの乱数を使用しているように見えるため、衝突が発生することはありません。

衝突の1%の確率で、約2,600,000,000,000,000,000の GUID を生成する必要があります。


3
それは私が考えたものですが、私はそれを排除できないことを確認したかっただけです。8年前のソフトウェアにどんな種類の奇妙なバグが現れるのか、あなたは決して知りません。:)
Jason Baker

6
実際、それはもう本当ではありません。これはv1 GUIDには当てはまりましたが、現在のv4 GUIDには当てはまりませんでした。詳細については、en.wikipedia.org / wiki / Globally_Unique_Identifier#Algorithmを参照してください。
グレッグビーチ、

96
原則として(最も生の形式で)、「GUIDの衝突は可能ですか?」という質問に対して「いいえ」と言うのは間違っているため、反対票を投じてください。それは非常に可能です。その可能性は小さいですが、それは可能です。私は平凡に聞こえるのが嫌いです-しかし、SOは簡潔で正確であることのすべてです。

13
"solve [1-exp [-(n ^ 2 /(2 * 2 ^ 128))]> 0.01、n]"をwolfram alphaに入力して、1%の結果を取得します...この数は大きいように見えますが、 1つのアプリケーションのコンテキストでは、それは確かに全世界に大きくはありません。地球上のすべてのコンピューターが真のGUIDを生成する場合、ナノ秒ごとにGUIDを生成できると仮定すると、1秒以内に1%の確率で衝突を引き起こします(これは最近ではおそらく非常に現実的です)。したがって、データベースIDにGUIDを使用する場合、それらは一意です。地球上で行われるすべての計算のGUIDはすぐに衝突します。
thesaint 2014年

11
「不可能」とは言えず、一定の量が発生したときに衝突が発生する可能性が1%あると言うことは、直接的な衝突です。正しい応答は理論的にする必要があります-はい、ランダムに衝突が発生する可能性があります。ただし、衝突の可能性は、小惑星が地球に衝突し、地球から跳ね返り、月に跳ね返り、次の1時間で再び地球に衝突する確率よりも統計的に小さくなります。
Baaleos 2016年

112

基本的にそれらは不可能です!、可能性は天文学的に低いです。

しかし...私が知っている世界で私が唯一の人物で、GUIDコリジョンが一度ありました(そうです!)。

そして私はそれを確信しており、それは間違いではなかったと思います。

Pocket PCで実行されていた小さなアプリケーションでは、操作の最後に、生成されたGUIDを持つコマンドを発行する必要がありました。サーバーで実行された後のコマンドは、実行日とともにサーバーのコマンドテーブルに格納されていました。デバッグしているときに、モジュールコマンドを発行し(新しく生成されたGUIDを添付)、何も起こりませんでした。私はもう一度それを行いました(操作の開始時にGUIDが1回だけ生成されたため、同じGUIDで)、そして何もせず、最終的にコマンドが実行されない理由を見つけようとして、コマンドテーブルを確認しました。現在と同じGUIDが3週間前に挿入されました。これを信じないで、私は2週間のバックアップからデータベースを復元しました。コードを確認したところ、新しいguidは間違いなく新しく生成されました。

編集:これが発生する可能性を大幅に増加させる可能性のあるいくつかの要因があり、アプリケーションはPocketPCエミュレーターで実行されており、エミュレーターには状態の保存機能があります。つまり、状態が復元されるたびにローカル時刻も復元されますまた、GUIDは内部タイマーに基づいています。また、コンパクトフレームワークのGUID生成アルゴリズムは、COMの例よりも完全ではない可能性があります...


38
賛成。状態を保存して再生すると、実際には重複したGUIDが生成されます。
ジョシュア

35
おそらく、これは「悪い」GUID実装でした。理論上の確率は非常に低いが、ポケットPC上にありました?彼らがそれらのオッズを「可能性は低いが、可能性のある」カテゴリーに引き上げる近道をとらなかったと誰が言っているのか。
Dave Dopson、2012年

9
何かが起こる可能性が非常に低いからといって、それが起こらないというわけではありません。
Renan

3
上記で述べたように、その可能性は非常に小さいため、間違いを犯したか、MSSQLが欠陥のあるPRNG(en.wikipedia.org/wiki/Pseudorandom_number_generator)を使用していると考えるのが安全です。たとえば、このPRNGは小さいサイズのシードで初期化される可能性があります。不良品のPRNGが(参照稀ではありませんschneier.com/paper-prngs.htmlを) -たとえばつの欠陥は、最近のAndroid SDKで発見された- android-developers.blogspot.com/2013/08/... + usenix.org/conference/woot14 / workshop-program / presentation /…
Alex

2
@Alex、間違いはエミュレーターからの「状態の保存と復元」でした。これは、エミュレーターのクロックを含むエミュレーターイメージ全体を復元します。そのため、1年間で数千回の復元操作の後、1つのGUID衝突が発生しました。間違いありましたね!
Pop Catalin 2014

34

それらは理論的には可能ですが、3.4E38の可能な数で、1年に数十兆のGUIDを作成する場合、1つの複製が作成される可能性は0.00000000006です(出典)。

2人のユーザーが同じGUIDで終わった場合、データがコピーまたは共有される原因となっているプログラムにバグがあることに賭けます。


「しかし、3.4E38の可能な数で」-いいえ。同じマシンでほぼ同時に生成された2つのGUIDは、非常に類似したGUIDになります。
カークストラウザー2008年

4
それはGUIDがどのように生成されるかに依存し、CPU時間またはミリ秒に基づく一部の実装では、(うまくいけば)ミリ秒から離れて生成された2つのGUIDが大幅に異なるため、それに基づいて計算が拡張されます。
Dalin Seivewright、2008年

4
マシンに複数のプロセッサがある場合、GUIDが時間とMACアドレスに基づいていると、各コアが同時に同じGUIDを発行する可能性があります。
AndyM 2010

12
きちんとしたGUIDの実装が行われないと確信しています
Guillaume86

1
@MatthewLock誕生日のパラドックスはソースでカバーされています。リンクを確認してください。
Zero3 '11年

21

まず、2つのGUIDの衝突の可能性を見てみましょう。他の回答が述べているように、誕生日のパラドックスのために2 ^ 128の1(10 ^ 38)ではありません。つまり、50%の確率で2つのGUIDが衝突する確率は、実際には2 ^ 64の1(10 ^ 19)はるかに小さいです。ただし、これは依然として非常に大きな数であり、そのため、妥当な数のGUIDを使用していると想定して衝突する可能性は低くなります。

また、多くの人も信じているように、GUIDにはタイムスタンプやMACアドレスが含まれていないことにも注意してください。これはv1 GUIDにも当てはまりましたが、現在はv4 GUIDが使用されています。これは単なる疑似乱数であり、時間とマシンに固有ではなくなっているため、衝突の可能性は間違いなく高くなります。

したがって、本質的には答えは「はい」です。衝突が発生する可能性があります。しかし、その可能性はほとんどありません。

編集:2 ^ 64と言うように修正


2
私はあなたのすべての事実に同意しますが、あなたの数学には注意してください。10 ^ 19分の1の確率で2つのGUIDが衝突するということは、セット内のGUIDの数によって異なります。そのためには、約2 ^ 32のGUIDが必要になるため、ほとんどすべての実際のシナリオでは、確率ははるかに低くなります。
DocMax 2008年

1
あなたにはタイプミスが1 in 10^64 (10^19)あります1 in 2^64 (10^19)。また、誕生日のパラドックスが2つの数字にしか当てはまらないのではないかと非常に混乱しています。en.wikipedia.org/wiki/Birthday_paradoxを見たと思います。次の表は、特定の重複確率で必要なGUIDの数を示しています。その表から、10 ^ 18で1の確率は2.6 * 10 ^ 10 GUIDを必要とし、2つのGUIDに近いものは必要ありません。
Tony Lee、

1つのポイント-v1のGUIDはまだ広く使用されており、特にデータベースでは望ましい特性を持っているため、MACアドレスに依存しています。UuidCreateSequentialとそのSQL ServerラッパーNewSequentialID(msdn.microsoft.com/en-us/library/windows/desktop/…)を参照してください
EBarr 2014

18

2つのランダムな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は統計的に一意であり、データベースから読み取ったデータは統計的にのみ正しいです。


10 ^ 28パケットの1未満が破損しているため、ネットワークを防御できない可能性がありますか?
Joshua

13

この場合、私はOccamのかみそりを良いガイドと見なします。GUIDの衝突が発生する可能性はほとんどありません。それはあなたがバグを持っているか、誰かがあなたのデータをいじっている可能性がはるかに高いです。


1
実際、この状況では、Occamのかみそりはまったく良いガイドではありません!OccamのRazorは、仮定が最も少ないケースが正しい可能性が最も高いと述べています。この状況では、GUID衝突のケースは実際にははるかに単純ですが、OccamのRazorは、ケースの1つが信じられないほどありそうにないことをすでに知っているこのような状況には適用されません。
ロックストック

11

WikipediaのGlobally Unique Identifierの記事を参照してください。GUIDを生成するにはいくつかの方法があります。どうやら古い(?)の方法はMacアドレス、非常に短い単位までのタイムスタンプ、および一意のカウンター(同じコンピューターで高速な世代を管理するため)を使用していたため、それらを複製することはほぼ不可能です。しかし、これらのGUIDは、ユーザーの追跡に使用できるため、削除されました...

Microsoftで使用されている新しいアルゴリズムがわかりません(一連のGUIDを予測できるとのことで、もうタイムスタンプを使用していないように見えますか?上記のMicrosoftの記事は別のことを言っています...)。

現在、GUIDは、名前によってグローバルに一意になるように注意深く設計されているため、不可能であるか、非常に確率が非常に低いというリスクがあります。私は他の場所を見るでしょう。





9

MACアドレスが重複しているイーサネットカードを備えた2台のWin95マシンは、特に建物の電源がオフになり、両方がまったく同時に起動する場合など、厳しく制御された条件下で重複したGUIDSを発行します。


2つの異なるマシンが同じイーサネットMACアドレスを持つことは一般的ですか?
Dave Lucre

@DaveLucre:いいえ、しかし事件は記録されています。
ジョシュア

これがどのように発生するのか本当に興味があります。各NICに対してランダムにMACを生成するVMの可能性は高いですか?MACが重複して製造される物理NICについて聞いたことがありません!可能であれば、作業中に大量のスパナを投げるようなものです!
Dave Lucre

うわー!リンク@Joshuaをありがとう!なんて巨大なねじ込み!
Dave Lucre

@DaveLucreすべてが同じMACで製造されている非常に安価なUSB NICをいくつか使用しました。しかし、もちろん、それはランダム性の数学とは関係なく、すべては製造業者の怠惰と関係があります。
rudolfbyker

5

私はこれを「ネットワーキングの人ではないので、完全に一貫性のない文章を後にするかもしれません。」で始めます。

イリノイ州立大学で働いていたとき、デルのデスクトップが2台あり、注文のタイミングが異なっていました。1つ目をネットワークに配置しましたが、2つ目をネットワークに配置しようとすると、異常なエラーが発生し始めました。多くのトラブルシューティングの結果、両方のマシンが同じGUIDを生成していることが判明しました(正確には何なのかわかりませんが、ネットワーク上で両方が使用できなくなりました)。デルは実際に両方のマシンを欠陥品として交換しました。


3
具体的にはGUIDでした。これは、マシンがネットワークに参加したときにマシンによって生成されたGUIDと関係があります。GUIDを同じにすることは不可能であると彼らが言ったので、Dellがマシンを交換するのに数週間かかりました。問題を再現することができ、デルはマシンを元に戻し、ネットワーク上で同じ結果を生成することができました。彼らは両方のマシンを交換してしまいました。先ほど述べたように、私はネットワーキングの専門家ではありませんが、GUIDの問題であったことを覚えています。
John Kraft、

5

私は、GUIDが魔法で一意であることが保証されているという気持ちのいい答えが好きな人を知っていますが、実際には、ほとんどのGUIDは121ビットの乱数にすぎません(7ビットがフォーマットに無駄に費やされています)。大きな乱数を快適に使用できない場合は、GUIDを使用しても快適ではありません。


11
また、ネットワークを使用しないことをお勧めします。またはコンピュータ。パリティビットはそれだけしかできません!
Rushyo

あなたは誤解しました。この投稿で私が言おうとしていたことは2つあります。1)大きな乱数が必要な場合は、大きな乱数を使用します。GUIDを大きな乱数として使用すると、不必要に誤解を招きます。(2)
リック・ヨルガソン2011年

4
私は完全に知っています。「大きな乱数を使いたくない場合」と述べました。しかし、GUIDは非常にユニークであるため、コンピューター内の他のほとんどすべての要素が、ランダムな操作であっても、よりランダムであることがわかります。(真の)GUIDの衝突が発生するよりも、異常なメモリグリッチがID列を破壊する可能性が高くなります。それらについて「不快」を感じるべきではありません。シナリオにとって理想的でない場合は問題ありませんが、特別な注意は必要ありません。
Rushyo

3
これはうまくいかないと思いますが、人々があなたに説明しようとしているのは、ネットワークカードやハードドライブなどの一般的なハードウェアのエラー検出メカニズムは、GUIDの衝突を取得するよりもエラーを検出しない可能性が高いアルゴリズムを使用しているためです。これらに依存し、GUIDに依存することもできます
Guillaume86

1
@リック、あなたの数がどれだけ大きいかに依存します。間違いなく、4バイトのintまたは8バイトのbigintではありません。GUID = 16バイトなので、同じ2 ^ 128通りの組み合わせを実現するには、カスタムの16バイトの大きな数の実装が必要です。したがって、一般的に言えば、「通常の」intまたはbigint乱数を使用する場合、GUID との衝突の可能性低くなります(それぞれについてランダムなアルゴリズムの考慮事項を除外します)。
Wim Hollebrandse

3

GUIDの生成に使用されたコードにバグがある可能性はありますか?はい、もちろん可能です。しかし、答えはコンパイラのバグの場合と同じです。独自のコードは桁違いにバグが多い可能性が高いので、まずそこを見てください。


2

もちろん可能です。可能性は低いですが、可能です。

同じマシンがすべてのGUID(サーバー)を生成しているため、マシン固有の情報に基づく「ランダムさ」の多くが失われることに注意してください。


1

にやにや笑うために、次のスクリプトを試してみてください...(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

これを繰り返し実行すると(1秒未満かかります)、非常に短い時間ギャップがあっても、最初の選択からかなり広い範囲が生成されます。これまでのところ、2番目の選択では何も生成されていません。


1
重複の可能性が50%になるには、カウンターの最後にさらに15個のゼロが必要です。しかし、ピートのためにそれをしないでください!
ジムバーチャル

0

ユーザーがネットワークカードを備えた別のマシンを使用している場合は不可能です。そうでない場合でも、それは非常にわずかな理論的リスクです。

個人的にはGUIDの衝突ではなくバグの可能性が高いため、他の場所を探します...

もちろん、GUIDを短くして短くしないでください。


GUIDはサーバー上で生成されるため、ユーザーのネットワークカードは機能しません。
トムリッター

0

確かにそれは可能であり、おそらく可能性さえあります。各GUIDが可能な数値スペースのランダムな部分にあるのとは異なります。2つのスレッドが1つを同時に生成しようとした場合、その周りにセマフォがある中央集中型GUID関数の一種を除外して、同じ値になる可能性があります。


0

次のような方法でGUIDの衝突を生成する可能性はほとんどありません。 NEWID()SQL Server関数の(もちろん、他の回答が強調しているように可能ですが)。彼らが指摘していないことの1つは、実際のブラウザーでJavaScriptでGUIDを生成している場合、衝突に遭遇する可能性が非常に高いということです。さまざまなブラウザーでのRNGに問題があるだけでなく、Googleスパイダーがそのような関数の結果をキャッシュしているように見えて、同じGUIDをシステムに繰り返し渡してしまう問題にも遭遇しました。

詳細については、こちらのさまざまな回答をご覧ください。

JavaScriptでUUIDを生成するときの衝突?

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