UUID
Universally Unique Identifier
UUID(Universally Unique Identifier)とは、ソフトウェア上でオブジェクトを一意に識別するための識別子である。UUIDは128ビットの数値だが、16進法による550e8400-e29b-41d4-a716-446655440000というような文字列による表現が使われることが多い。元来は分散システム上で統制なしに作成できる識別子として設計されており、したがって将来にわたって重複や偶然の一致が起こらないという前提で用いることができる。マイクロソフトによる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)"」の一部として文書化されている。またIETFはUUIDに関してを公開している。
UUIDには歴史的経緯から数種類のバリアント(変種)があり、現行の規格で定められているのはそのうちの1つである。16進表記をした場合にxxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxxのNの桁の上位ビットがバリアントを示す。現行の規格では上位2ビットが102であることが定められているので、16進表記では8、9、A、Bのいずれかとなる。これ以外のバリアントは、規格制定以前に生成されたUUIDとの後方互換性、あるいは将来のために予約されている。全てが0のUUIDも、こうしたバリアントの一つである。
現行規格で定められているバリアントには、さらに生成方法が異なる複数の種類があり、これをバージョンと呼んでいる。16進表記をした場合にxxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxxのMの桁がバージョン(1から5)を示す。なお以降の16進表記でNの桁が小文字になっているのはバリアントの情報が含まれることを示す。
もともとの生成法である、時刻と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アドレスは人為的に差し替え可能であり、必ずしもあてにはできない。
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)となる。
ドメイン名などなんらかの一意な名前(バイト列)を用いたUUIDで、ハッシュ関数としてMD5(バージョン3)またはSHA1(バージョン5)を利用したもの。すでに一意であることがわかっている物があり、それと(事実上)1対1に対応するUUIDが必要な場合に用いられる。16進表記ではHHHHHHHH-HHHH-3HHH-hHHH-HHHHHHHHHHHH、HHHHHHHH-HHHH-5HHH-hHHH-HHHHHHHHHHHHとなり、そのほとんどがハッシュ値に由来する(H:122ビット)。用いる名前はFQDN、URL、X.500 DNなど何でもよいが、それぞれの名前空間自体に固有のUUIDが割り当てられている必要がある。名前空間のUUID(バイト列)と名前を繋げてハッシュ値を計算し、それを名前のUUIDへと変換する。MD5の場合の変換は、128ビットのハッシュ値にバリアント (102) とバージョン (00112) を上書きする。SHA1は160ビットのハッシュだが、下位32ビットを切り捨て128ビットにした上で、同様にバリアント (102) とバージョン (01012) を上書きすることで変換する。
バージョン4のUUIDは、乱数により生成される。他のUUIDと同様、バージョン4であることを示すために4ビットが使われ、バリアント(バリアント1と2に対して、それぞれ102または1102)を示すために2または3ビットが使われる。したがって、バリアント1(つまりほとんどのUUID)では、ランダムなバージョン4のUUIDの場合、6ビットはバリアントとバージョンビットのためにあらかじめ決定されており、ランダムに生成される部分には122ビットが残されている。よって、バージョン4バリアント1のUUIDは、2122すなわち5.336(5.31澗、5.31undecillion)通り存在する。16進表記では、RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRRとなる。バージョン4バリアント2のUUID(レガシーなGUID)の場合、バリアントに3ビットが確保されるため、UUIDの総数は半分になる。
有名な使用例としては、ext2/ext3/ext4ファイルシステムのユーザースペースのツール、LUKS暗号パーティション、GNOME、KDE、macOSなどがある。これらのほとんどは、セオドア・ツォーによるオリジナルの実装に由来する。
Solarisでは、カーネルパニックが発生した場合において、クラッシュダンプのデータをFault Management Eventと照合 (pairing) する目的で、実行中のオペレーティングシステムのインスタンスを特定するためにUUIDが使用されている。