UUID は Universally Unique Identifier の略で、一意の識別子です。
0x01 バージョン#
UUID には異なるバージョンがあり、各バージョンには異なる適用シナリオがあります。たとえば、バージョン 4 ではすべての可変要素をランダムに生成することが推奨されています。多くのシナリオでは、これは非常に便利な実装方法です。バージョン 1 では、タイムスタンプ + クロックシーケンス + ノード情報(マシン情報)が使用され、いくつかの分散システムシナリオでは厳密なグローバルユニーク性が保証されます。Twitter の snowflake は、UUID バージョン 1 の簡略版と見なすことができます。現在までに、UUID は 5 つの実装バージョンがあります。
- バージョン 1:UUID の定義に従って各フィールドの意味を厳密に実装し、変数要素にはタイムスタンプ + クロックシーケンス + ノード情報(Mac アドレス)が使用されます。
- バージョン 2:基本的にはバージョン 1 と同じですが、DCE(IBM の分散コンピューティング環境)と主に関連しています。ただし、このバージョンは ietf で具体的に説明されておらず、代わりに DCE 1.1:Authentication and Security Services のドキュメントで具体的な実装が説明されています。そのため、このバージョンは現在ほとんど使用されず、多くの実装では無視されています。
- バージョン 3:名前と名前空間に基づくハッシュを使用した変数要素の実装で、バージョン 3 では md5 ハッシュアルゴリズムが使用されます。
- バージョン 4:ランダムまたは擬似ランダムな変数要素の実装です。
- バージョン 5:名前と名前空間に基づくハッシュを使用した変数要素の実装で、バージョン 5 では sha1 ハッシュアルゴリズムが使用されます。
UUID のバージョンに関係なく、その構造は同じです。この構造はバージョン 1 に従って定義されており、他のバージョンではバージョン 1 のいくつかの変数要素が変更されているだけです。
0x02 基本構造#
UUID は 128 ビット(16 バイト(128 ビット))の長さであり、16 進数の値(4 ビットごとに 1 つの値)で表されます。値は 32 個の 16 進数で構成され、4 つのハイフンで区切られています。区切り文字を含めると、UUID は 36 文字です。例:3e350a5c-222a-11eb-abef-0242ac110002。
UUID の形式は次のようになります:xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
N の位置は 8、9、a、b のいずれかです。
M の位置はバージョン番号を表し、UUID の標準実装には 5 つのバージョンがあるため、1、2、3、4、5 のいずれかです。
壱 Timestamp - タイムスタンプ#
タイムスタンプは 60 ビットの符号なし整数です。バージョン 1 の UUID の場合、1582-10-15 00:00:000000000 から現在の UTC 時間まで、100 ナノ秒ごとに増加します。UTC 時間を取得できないシステムの場合は、UTC を取得できないため、統一的にローカルタイムを使用することができます(実際には、システムのタイムゾーンが同じであれば問題ありません)。
タイムスタンプがあるため、構造図の time_low、time_mid、time_hi がわかります。
time_low
はタイムスタンプの 60 ビットのうち 0〜31 ビットで、合計 32 ビットです。
time_mid
はタイムスタンプの 60 ビットのうち 32〜47 ビットで、合計 16 ビットです。
time_hi_and_version
フィールドは、version と time_hi の 2 つの部分からなります。version は 4 ビットでビット数を占有し、最大 31 のバージョンをサポートできます。time_hi は残りの 12 ビットで、合計 16 ビットです。
弐 Clock Sequence - クロックシーケンス#
UUID を計算するマシンが時間調整を行った場合、またはノード ID が変更された場合(ホストがネットワークカードを交換した場合)、他のマシンとの競合を避けるために、再度生成される UUID の一意性を保証するために変数要素が必要です。
実際のところ、クロックシーケンスの変化アルゴリズムは非常に単純です。時間の調整やノード ID の変更がある場合、ランダムな数値を使用するか、元のクロックシーケンス値に 1 を加えることもできます。クロックシーケンスは合計 14 ビットです。
clock_seq_low
はクロックシーケンスの 0〜7 ビットで、合計 8 ビットです。
clock_seq_hi_and_reserved
フィールドには、reserved と clock_seq_hi の 2 つの部分が含まれます。clock_seq_hi はクロックシーケンスの 8〜13 ビットで、合計 6 ビットです。reserved は 2 ビットで、通常は 10 に設定されます。
参 node - ノード情報#
ノードは 48 ビットの符号なし整数であり、バージョン 1 の UUID の場合、IEEE 802 MAC アドレス(ネットワークカードの MAC アドレス)が選択されます。システムに複数のネットワークカードがある場合、有効なネットワークカードのいずれかをノードデータとして使用できます。ネットワークカードがないシステムの場合、値はランダムな数値になります。
0x03 異なるバージョンの違い#
上記の内容で UUID の構造が説明されました。基本的に、この構造は UUID バージョン 1 の定義です。見るとわかるように、変数要素にはタイムスタンプ、クロックシーケンス、ノードが含まれていますが、異なるバージョンではこれらの変数要素の意味が異なります。
バージョン 4 では、タイムスタンプ、クロックシーケンス、ノードはすべてランダムまたは擬似ランダムです。
しかし、バージョン 3 と 5 では、名前と名前空間に基づいたハッシュアルゴリズムに基づいています。
名前と名前空間は、多くのプログラミング言語の名前空間やクラス名と同様であり、基本的な要件は、name + namespace がハッシュ文字列を一意に決定することです。つまり、同じ namespace + name を使用して同じハッシュアルゴリズム(たとえば、version3 の md5)を使用すると、同じ結果が生成されますが、異なる namespace の同じ name から生成される結果は異なります。
バージョン 3 とバージョン 5 の両方の変数要素は、ハッシュアルゴリズムによって保証されます。バージョン 3 は md5、バージョン 5 は sha1 を使用します。
以上です。このチュートリアルはここまでです〜 Cloud Shell の体験が良いと思った場合は、今後も更新を続けます!この記事がお役に立てた場合は、スポンサーシップをご検討いただけますか?ありがとうございました〜