UUID

ソフトウェア上でオブジェクトを一意に識別する識別子

UUIDUniversally Unique Identifier)や汎用一意識別子(はんよういちいしきべつし)やユニバーサル一意識別子(ユニバーサルいちいしきべつし)は、ソフトウェア上でオブジェクトを一意に識別するための識別子である。

Universally Unique Identifier
UEFI変数として使用されるUUID/GUID
頭字語 UUID
管理団体
桁数 128ビット(数値)
36文字(文字列表記)
18cd3748-9a76-4a05-8c69-ba0b8c1a9d17
ウェブサイト RFC 9562
ISO/IEC 9834-8:2014

UUIDは128ビットの数値だが、16進法による550e8400-e29b-41d4-a716-446655440000というような文字列による表現も仕様で定められている。

分散システム上での利用を考慮して設計されており、統制なしに作成しても重複や偶然の一致が事実上起こらないものとして使用できる[注釈 1]

マイクロソフトによるGUIDは、UUIDの実装の1つとされる。

規格

編集

Network Computing Systemで導入され、それをDistributed Computing Environment(DCE)の一部としてOpen Software Foundation(OSF)が標準化し、「ISO/IEC 11578:1996 "Information technology -- Open Systems Interconnection -- Remote Procedure Call (RPC)"」の一部として文書化されていた。その後、ISOは ISO/IEC 9834-8:2005[1]、ISO/IEC 9834-8:2008[2] 、ISO/IEC 9834-8:2014[3] と改訂した。ISOの仕様はRFCを追いかけていて、基本的に同一である。

またIETFはUUIDに関して2005年7月にRFC 4122 を制定し、2024年5月にRFC 9562 に改訂した。

バリアント

編集

UUIDには歴史的経緯から数種類のバリアント(変種)があり、現行の規格で定められているのはそのうちの1つである。16進表記をした場合にxxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxxのNの桁の上位ビットがバリアントを示す。RFCでは上位2ビットが102であることが定められているので、16進表記では8、9、A、Bのいずれかとなる。これ以外のバリアントは、RFC制定以前に生成されたUUIDとの後方互換性、あるいは将来のために予約されている。全てが0のUUIDも、こうしたバリアントの一つである。

Msb0 Msb1 Msb2 バリアント
0

Network Computing Systemへの後方互換性のために予約
1 0
RFCやISOで使用しているバリアント
1 1 0 マイクロソフトがCOMで用いているGUIDとの後方互換性のために予約
1 1 1 将来のために予約

バージョン

編集

RFCで定められている仕様には、さらに生成方法が異なる複数の種類があり、これをバージョンと呼んでいる。16進表記をした場合にxxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxxのMの桁がバージョン(1から8)を示す。なお以降の16進表記でNの桁が小文字になっているのはバリアントの情報が含まれることを示す。

RFC 9562 では、各バージョンに関して、仕様制定時の2024年5月現在として、以下のように問題点を記載している。一般の用途として推奨されるのはバージョン4と7になる。バージョン(4ビット)とバリアント(2ビット)を記載するために合計6ビット消費しているが、UUIDと互換であることが不要であれば、バージョン4の代わりに128ビット乱数を、バージョン7の代わりにULID[4]が使用できる。

バージョン 問題点
1 色々と問題があるため、可能ならバージョン7を使用すべき(SHOULD)。
2 DCE用なのでRFCの対象外。
3 MD5を使用しているが、MD5は脆弱なので、他のを使うべき(SHOULD)。
4 問題なし。乱数のみによる生成。
5 SHA-1を使用しているが、SHA-1は脆弱で、NISTは2030年12月31日に仕様を廃止予定[5]。代わりにSHA-2を使用する場合は、バージョン8とすること(MUST)。
6 バージョン1と互換性を保ちながら、時間順でソートできるようにしたものだが、バージョン7を使用するべき(SHOULD)。
7 問題なし。先頭にミリ秒単位の時刻を付けて、時間順でソートできるもの。
8 実験用。

バージョン1

編集

もともとの生成法である、時刻とMACアドレスを利用したUUID。16進表記をするとTTTTTTTT-TTTT-1TTT-sSSS-AAAAAAAAAAAAのような構造になっており、それぞれタイムスタンプ(T:60ビット)、クロックシーケンス(S:14ビット+上位2ビットが102)、ノード(A:48ビット)からなる。

タイムスタンプはUUID生成時刻(協定世界時)における1582年10月15日(カトリック教会におけるグレゴリオ暦の実施日)0時0分からの経過時間を100ナノ秒単位で計測した数値。60ビットで3653年分の時刻を扱えるため、西暦5235年までこの方法を用いることができる。

ノードはUUIDを生成した装置を一意に示す値で、普通はネットワークカードに(通常一意に)与えられているMACアドレスを用いる。複数あるときは任意に一つを選択してよい。またMACアドレスが存在しない場合には、乱数を生成してマルチキャストビットを立てて用いることができる。

クロックシーケンスは、同一の機器で(同一のネットワークインタフェース(MACアドレス)を持ち)、かつ、時計の精度などのために同一のタイムスタンプにおいてUUIDを生成しなければならない場合に、同一のUUIDが重複しないように順次変更させて使う値である。この値はインクリメントなどで変更しなければならず、乱数列を使用してはならない。14ビットしかないので、乱数列では誕生日パラドックスにより容易に同一のUUIDを生成し得るからである。

また、機器の時刻管理やうるう秒による時刻の巻き戻りのために、あるいは、時刻が進んでいる装置から遅れている装置にネットワークカードを移設したような場合にも重複が発生し得る。前者への対応として、クロックシーケンスは新しいタイムスタンプの度にリセットしたりせず、最後に生成した時の状態を保持し、継続して更新しなければならない。しかし、後者への対応は、前にそのカードを使っていた装置で生成されたクロックシーケンスを知ることは難しいため、乱数で再初期化せざるを得ない。

バージョン1のUUIDの特徴として、同じ装置で生成された事実やUUID生成の前後関係を知ることができる。しかし、MACアドレスは人為的に差し替え可能であり、必ずしもあてにはできない。

RFC 9562 ではバージョン1よりもバージョン7を使うべき(SHOULD)としている。

バージョン2

編集

DCEシステムにおける権限認可を目的に設計されたもので、バージョン1のUUIDの一部を、POSIXのユーザーIDやグループIDで差し替えたもの。16進表記ではIIIIIIII-TTTT-2TTT-dDDD-AAAAAAAAAAAAとなり、タイムスタンプの一部とクロックシーケンスをそれぞれローカルID(I:32ビット)とローカルドメイン(D:14ビット+上位2ビットが102)で置き換えている。ローカルドメインはローカルIDの種類を示す値で、ユーザーIDを用いる場合には0(16進表記で8000)、グループIDを用いる場合には1(16進表記で8001)となる[6]

バージョン3/5

編集

ドメイン名などなんらかの一意な名前(バイト列)を用いたUUIDで、ハッシュ関数としてMD5(バージョン3)またはSHA-1(バージョン5)を利用したもの。すでに一意であることがわかっている物があり、それと(事実上)1対1に対応するUUIDが必要な場合に用いられる。16進表記ではHHHHHHHH-HHHH-3HHH-hHHH-HHHHHHHHHHHHHHHHHHHH-HHHH-5HHH-hHHH-HHHHHHHHHHHHとなり、そのほとんどがハッシュ値に由来する(H:122ビット)。用いる名前はFQDNURLX.500 DNなど何でもよいが、それぞれの名前空間自体に固有のUUIDが割り当てられている必要がある。名前空間のUUID(バイト列)と名前を繋げてハッシュ値を計算し、それを名前のUUIDへと変換する。MD5の場合の変換は、128ビットのハッシュ値にバリアント (102) とバージョン (00112) を上書きする。SHA-1は160ビットのハッシュだが、下位32ビットを切り捨て128ビットにした上で、同様にバリアント (102) とバージョン (01012) を上書きすることで変換する。

バージョン4

編集

バージョン4のUUIDは、乱数により生成される。他のUUIDと同様、バージョン4であることを示すために4ビットが使われ、バリアント(バリアント1と2に対して、それぞれ102または1102)を示すために2または3ビットが使われる。したがって、バリアント1(つまりほとんどのUUID)では、ランダムなバージョン4のUUIDの場合、6ビットはバリアントとバージョンビットのためにあらかじめ決定されており、ランダムに生成される部分には122ビットが残されている。よって、バージョン4バリアント1のUUIDは、2122すなわち約5.3×1036通り存在する[注釈 2][注釈 3]。16進表記では、RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRRとなる。バージョン4バリアント2のUUID(レガシーなGUID)の場合、バリアントに3ビットが確保されるため、UUIDの総数は半分になる。

バージョン6

編集

バージョン1の改変で、time_low, time_mid, time_high の順番を逆にして、time_highが上位ビットに来るようにして、時間順でソートできるようにして、データベースでの局所性を高められる。古いバージョン1との互換性が不要であれば、RFC 9562 はバージョン6ではなくバージョン7を使うべき(SHOULD)としている。

バージョン7

編集

バージョン7はバージョン6と同様に時間順でソート可能で、ミリ秒単位のUNIX時間を先頭48ビットに付けている。それにより、時刻が近いデータをまとめられるので、データベースのプライマリキーとして使用した場合、局所性を高められる。16進表記では、TTTTTTTT-TTTT-7RRR-rRRR-RRRRRRRRRRRRとなる。

128ビットの構成

  1. ミリ秒単位のUNIX時間を48ビット。10889年まで表現可能。
  2. バージョン。定数01112
  3. 乱数12ビット
  4. バリアント。定数102
  5. 乱数62ビット

バージョン8

編集

実験もしくはベンダー固有の用途用。バージョンとバリアント以外の部分は自由に使える。

バージョン9から15

編集

将来の使用のために予約。

UUID から派生した類似のものとして ULID (Universally Unique Lexicographically Sortable Identifier) がある。内容としてはUUIDバージョン7と近く(ULIDの方が古く RFC 9562 では参考にしたものの1つとして記載している)、ミリ秒単位のUNIX時間を48ビット、乱数80ビットから構成される。文字列に変換する際は、CrockfordのBase32を使用し、I, L, O, U は見間違いを防ぐために含めない。文字列表記では26文字になる。[4]

使用例

編集

有名な使用例としては、ext2/ext3/ext4ファイルシステムのユーザー空間のツール[注釈 4]LUKS暗号パーティション、GNOMEKDEmacOS[注釈 5]などがある。これらのほとんどは、セオドア・ツォーによるオリジナルの実装に由来する[11]

Solarisでは、カーネルパニックが発生した場合において、クラッシュダンプのデータをFault Management Eventと照合 (pairing) する目的で、実行中のオペレーティングシステムのインスタンスを特定するためにUUIDが使用されている[12]

Bluetooth Low Energyでは、GATTサービスやGATTキャラクタリスティックの識別にUUIDを使用する。一部のUUIDは規格によって特定の用途に予約されている。

クロスプラットフォームプログラミング言語ではUUIDを生成したり文字列と相互変換したりするための機能が標準ライブラリとして用意されていることが多い。

オペレーティングシステムによっては、UUIDを生成するコマンドラインツールuuidgenが用意されていることもある[20][21]Microsoft Windowsの場合はWindows SDKに付属する[22]Windows APIにおける実装についてはGUIDを参照のこと。

脚注

編集

注釈

編集
  1. ^ 乱数に基づくUUID version 4の場合、2122すなわち約5.3×1036通り存在し、正しく生成されていれば、誕生日のパラドックスによっても、2つのIDが偶然一致するまでには期待値で261個のIDの生成が必要である。
  2. ^  
  3. ^ 5.3、5.3 undecillionとも。命数法およびen:Names of large numbersも参照のこと。
  4. ^ たとえば、e2fsprogsutil-linux英語版が提供する libuuid を使用している。LinuxのlibuuidはLGPLv2でライセンスされており[7]、e2fsprogsパッケージの一部として含まれてもいる[8]
  5. ^ Mac OS X 10.4に対応するAppleのLibc-391における"gen_uuid.c"を参照のこと[9][10]

出典

編集

関連項目

編集

外部リンク

編集