UUID(汎用一意識別子)とは
UUID(Universally Unique Identifier)とは、
ソフトウェアの世界でオブジェクトを一意に識別するために用いられる
識別子です。汎用一意
識別子、ユニバーサル一意
識別子とも呼ばれます。UUIDは128
ビットの数値で構成されますが、通常は16進数表現の文字列(例:550e8400-e29b-41d4-a716-446655440000)で表されます。
UUIDは
分散システムでの利用を考慮して設計されており、異なる場所で生成されたUUIDが偶然に重複する可能性は極めて低いとされています。この特性から、データベースの主キーや、ネットワーク上の
識別子として広く利用されています。
マイクロソフトのGUID(Globally Unique Identifier)は、UUIDの一実装とみなされています。
UUIDの規格
UUIDは、もともとNetwork Computing Systemで導入され、
Distributed Computing Environment(DCE)の一部として
Open Software Foundation(OSF)によって標準化されました。
その後、ISO(
国際標準化機構)がISO/IEC 11578:1996として文書化し、ISO/IEC 9834-8:2005、ISO/IEC 9834-8:2008、ISO/IEC 9834-8:2014と改訂を重ねています。ISOの仕様はIETF(インターネット技術標準化委員会)のRFC(
Request for Comments)を参考に作られており、基本的には内容が同じです。
IETFは2005年7月にRFC 4122を制定し、2024年5月にはRFC 9562に改訂しました。RFC 9562が最新の仕様となります。
UUIDのバリアント(変種)
UUIDには、歴史的な経緯から複数のバリアント(変種)が存在します。現在規定されているのはそのうちの一つで、16進数表記した際の`xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx`という形式において、`N`の部分の上位
ビットがバリアントを示します。
RFCでは上位2
ビットが`10`(16進数表記では`8`、`9`、`A`、`B`)と定められています。その他のバリアントは、RFC制定以前のUUIDとの互換性や、将来的な拡張のために予約されています。すべての
ビットが`0`のUUIDも、バリアントの一つです。
UUIDのバージョン
UUIDの仕様には、生成方法が異なる複数のバージョンが存在します。16進数表記の`xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx`の`M`の部分がバージョンを表します(1から8)。RFC 9562では、各バージョンについて、制定時(2024年5月)の状況を踏まえた上で、推奨される利用方法が示されています。一般的には、バージョン4と7が推奨されます。
UUIDのバージョンとバリアントの情報を格納するために6
ビット消費されていますが、UUIDとの互換性を考慮しない場合は、バージョン4の代わりに128
ビット乱数、バージョン7の代わりにULIDを使用することができます。
バージョン1
バージョン1は、時刻とMACアドレスを基にUUIDを生成する初期の方法です。UUIDの構造は`TTTTTTTT-TTTT-1TTT-sSSS-AAAAAAAAAAAA`となり、タイムスタンプ(T)、クロックシーケンス(S)、ノード(A)から構成されています。
タイムスタンプは1582年10月15日0時0分からの経過時間を100ナノ秒単位で計測したもので、60
ビットで3653年分を表現可能です。ノードはUUIDを生成した装置を識別する値で、通常はネットワークカードのMACアドレスが使用されます。クロックシーケンスは、同一機器で同じタイムスタンプでUUIDを生成する際に、重複を防ぐために用いられます。
バージョン1のUUIDは、同じ装置で生成されたことや、生成の前後関係を特定できます。しかし、MACアドレスは偽装可能であるため、完全に信頼できる情報ではありません。RFC 9562では、バージョン1よりもバージョン7の使用が推奨されています。
バージョン2
バージョン2は、DCEシステムにおける権限認可を目的に設計されたものです。バージョン1の一部を、
POSIXのユーザーIDやグループIDで置き換えたものです。UUIDの構造は`IIIIIIII-TTTT-2TTT-dDDD-AAAAAAAAAAAA`となり、タイムスタンプの一部とクロックシーケンスが、ローカルID(I)とローカルドメイン(D)に置き換わっています。ローカルドメインは、ローカルIDの種類を示します。
バージョン3/5
バージョン3と5は、ドメイン名などの一意な名前からUUIDを生成する方法です。ハッシュ関数として、バージョン3では
MD5、バージョン5では
SHA-1が用いられます。既存の一意な名前とUUIDを1対1で対応させる必要がある場合に利用されます。UUIDの構造は`HHHHHHHH-HHHH-3HHH-hHHH-HHHHHHHHHHHH`または`HHHHHHHH-HHHH-5HHH-hHHH-HHHHHHHHHHHH`で、ハッシュ値が大部分を占めます。名前空間のUUIDと名前を連結してハッシュ値を計算し、UUIDに変換します。
バージョン4
バージョン4は、乱数を用いてUUIDを生成する方法です。他のUUIDと同様にバージョンとバリアントの情報を持ちますが、残りの
ビットは完全にランダムな値で埋められます。バージョン4バリアント1のUUIDは約5.3×1036通り存在します。
バージョン6
バージョン6はバージョン1を改良したもので、時間順にソートしやすいようにタイムスタンプの順序を入れ替えています。データベースでの局所性を高められますが、RFC 9562では、古いバージョン1との互換性が不要であれば、バージョン7の使用が推奨されています。
バージョン7
バージョン7は、バージョン6と同様に時間順でソート可能で、ミリ秒単位のUNIX時間を先頭に配置します。これにより、時刻が近いデータをまとめられるため、データベースのプライマリキーとして利用する際に効率的です。UUIDの構造は`TTTTTTTT-TTTT-7RRR-rRRR-RRRRRRRRRRRR`です。128
ビットの構成は、ミリ秒単位のUNIX時間48
ビット、バージョン定数4
ビット、乱数12
ビット、バリアント定数2
ビット、乱数62
ビットです。
バージョン8
バージョン8は、実験やベンダー固有の用途のために予約されています。バージョンとバリアント以外の部分は自由に利用できます。
バージョン9から15
バージョン9から15は、将来の利用のために予約されています。
ULID
ULID(Universally Unique Lexicographically Sortable Identifier)は、UUIDから派生したもので、UUIDバージョン7に近い特徴を持ちます。ミリ秒単位のUNIX時間48
ビットと乱数80
ビットで構成されます。文字列に変換する際は、CrockfordのBase32を使用し、`I`, `L`, `O`, `U`の文字は含めません。文字列長は26文字です。
UUIDの利用例
UUIDは、様々な
ソフトウェアやシステムで利用されています。以下に代表的な例を挙げます。
ファイルシステム: ext2/ext3/ext4ファイルシステムのツール
暗号化: LUKS暗号パーティション
デスクトップ環境: GNOME、KDE
オペレーティングシステム: macOS
クラッシュダンプ: Solarisでのカーネルパニック時のデータ照合
Bluetooth: Bluetooth Low EnergyにおけるGATTサービスやキャラクタリスティックの識別
また、多くの
プログラミング言語では、UUIDを生成したり文字列と相互変換したりする機能が標準ライブラリとして提供されています。例えば、
Java、
Python、
.NET、
C++(
Boost C++ライブラリ)、
Objective-C/Swiftなどが挙げられます。
オペレーティングシステムによっては、UUIDを生成するコマンドラインツールも用意されています。
Microsoft Windowsでは、Windows SDKに付属しています。
まとめ
UUIDは、
ソフトウェアの世界で一意の
識別子として広く利用されています。
分散システムでの利用を考慮した設計であり、その構造や生成方法には様々なバージョンが存在します。適切なバージョンを選択することで、効率的なシステム構築に貢献します。