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 バイト)であり、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 が変更された場合(ホストのネットワークカードが変更された場合)、他のマシンとの競合を防ぐために、変数要素を変更する必要があります。
実際のところ、クロックシーケンスの変更アルゴリズムは非常にシンプルです。時間調整やノード 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 を使用すると、同じハッシュアルゴリズム(たとえば、バージョン 3 の md5)を使用して計算された結果は同じである必要がありますが、異なる namespace の同じ name から生成された結果は異なります。
バージョン 3 とバージョン 5 の両方の変数要素は、ハッシュアルゴリズムによって保証されます。バージョン 3 では md5、バージョン 5 では sha1 が使用されます。
さて、このチュートリアルはここまでです。Cloud Shell の体験が良いと思った場合は、今後も更新を続ける予定です!この記事がお役に立った場合は、サポートをご検討いただけますか?ありがとうございました!