32188


UnityのC#でゲームを作っており、  
モバイル端末間のデータ引継ぎに関して調査しております。  
端末固有のIDを取得または生成したいと考えており、  
その過程で件名のGuid構造体を見つけました。

下記、MSDNによると  
"GUID は、128 ビットの整数 (16 バイト) 一意の識別子が必要であれば常に、  
すべてのコンピューターおよびネットワークの間で使用できます。  
このような識別子には、重複する可能性は非常に低いができます。"  
<https://msdn.microsoft.com/ja-jp/library/system.guid(v=vs.110).aspx>

とあるのですが、  
"すべてのコンピューターおよびネットワークの間で使用できます。"と  
いう部分が非常にひっかかっております。

そもそも全端末でほぼ異なる一意なIDがなぜ作れるのか？

モバイル間でどのIDが発行されたかを知るにはサーバーサイドなどで  
アクティベーションを管理していないと不可能だと思うのですが、  
ここでいう"すべてのコンピューターおよびネットワークの間で使用できます。"とは  
どういう意味でしょうか？

以上、よろしくお願いします。

■環境  
Windows10  
Unity5.3.5f1  
（Unityなので.Netは2.0 C#は3.0だと思われます。）


CC BY-SA 3.0
2017-01-27T03:31:11.367
32184
2017-02-11T02:35:29.243
5261
question
c#
Guid 構造体およびGuid.NewGuid メソッド ()の一意なIDについて


> そもそも全端末でほぼ異なる一意なIDがなぜ作れるのか？

前提を見逃しています。識別子である限り何ビット用意したとしても重複する可能性は排除できません。重複する前提で設計を行ってください。

> このような識別子には、重複する可能性は非常に低いができます。  
>  Such an identifier has a very low probability of being duplicated.

このような記述がある通り「重複する可能性は非常に低い」でしかありません。


CC BY-SA 3.0
2017-01-27T04:44:59.610
32187
2017-01-27T04:44:59.610
4236
32184
answer


GUID という用語は Microsoft による UUID の実装のひとつと解釈してＯＫです。  
そして UUID の解説はたとえば <https://ja.wikipedia.org/wiki/UUID>

「暗号学的単方向ハッシュ関数」というのは入力が少し違うと結果の値が大きく変わるような関数です。これの入力として各 PC ごとに異なるであろう値 (作成時刻の
nsec 値とか MAC アドレスとかキー操作時間エントロピーとか) を渡すと毎回違う値が得られます。これが UUID です。

> すべてのコンピューターおよびネットワークの間で使用できます。

というのは「まったく無関係なマシンがお互いに連絡を取り合ったりせず独立に UUID を生成するような条件下でも、その UUID
が完全一致する可能性が極めて低い」という意味です。

言い換えれば、「自分が今生成した UUID が、過去未来、ネットワークの全マシン上で生成された別の UUID
と完全一致する可能性はきわめて低いがゆえに一意の識別子として使えます」です。

極めて低いだけで完全に０ではないよ、と提示 MSDN 解説ページ（の原文）は主張しています
(機械翻訳日本語ページより、原文英語ページのほうが意味が理解しやすいです) 。

UUID がたまたま一致する確率は、キー長と誕生日のパラドックスから決まり Wikipedia の解説では 1/(2^61) と書かれています。

厳密さをさておき、ちょっと計算してみましょう。

１秒に１億個の UUID を生成・比較できるマシンが UUID を生成して比較し続けるとします。  
１億 = 2^26.57  
１年は 365*24*3600 秒なので 2^24.91  
61-26.57-24.91 = 9.52 なので 2^9.52 年すなわち 734 年かけると一致することがある。

UUID が一致したら何がどうまずいか？あたりは事前に検討が必要です。  
まあ普通に「善意の UUID ユーザが正しく運用すれば」そう簡単に一致はしませんけど、ネットワーク電文を読み取って UUID
を手に入れた攻撃者が悪意を持って使ったら？とかは一度考えてもいいでしょう。


CC BY-SA 3.0
2017-01-27T05:11:03.250
32188
2017-01-27T05:11:03.250
8589
32184
answer


マイクロソフトは[Windows 2000](https://msdn.microsoft.com/en-
us/library/aa446557.aspx)から`UUID version
4`のアルゴリズムを採用していて、乱数をもとに一意といえるIDを生成しています。（他の回答のとおり、衝突する可能性が極めて低いのです。注意点としては、結果が一意であることに重きをおいていて、結果が暗号学的にランダムというわけではないです）

`UUID version
1`のアルゴリズムは"MACアドレスとタイムスタンプ”を用いるため、マシン毎に一意な値を生成するという点では利点があるかもしれません。が、マイクロソフトはセキュリティの懸念から採用していないそうです。(自分には説明できません。MACアドレス・タイムスタンプは比較的簡単に偽造できるからでしょうか)
ちなみに、[version 1のUUIDを生成する手段](https://stackoverflow.com/questions/9411673/how-
to-generate-a-version-1-guid-in-net)もあるようです。


CC BY-SA 3.0
2017-01-28T06:36:31.863
32217
2017-01-28T06:47:37.840
2017-05-23T12:38:56.083
-1
2238
32184
answer


> 極めて低いだけで完全に０ではない

結局のところ↑をどう捉えるか、です。  
冷たいたようですが、判断は自分でするべきだと思います。

個人的には、ちょっとしたツール程度や試作レベルなら「一意である」ことにして先に進みますが、プロダクションでは DB
で管理された、システム的に一意な値を使用することが多いです。

また、非常に大規模なシステムでスケールアウトが必要であり、毎回 DB 問い合わせなどやってられない場合は、たっまつに DB
管理された一意な値を振り出して引き渡しておき、実使用する際にはさらにそれに伝達経路や処理ノードなどに割り当てられた一意な値、タイムスタンプや情報を付与することで厳密な一意性を担保しています。

要するに、GUID
の一意性は「極めて低いだけで完全に０ではない」のは明らかなので、それをどう捉えてどのように実装には反映するかの判断は自分（達）である、ということです。

もちろん、その判断をするための材料として本件のような質問をすることは意義あることだと思います。


CC BY-SA 3.0
2017-02-11T02:35:29.243
32574
2017-02-11T02:35:29.243
3033
32184
answer