UUID

**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)"」の一部として文書化されていた。その後、ISOは ISO/IEC 9834-8:2005、ISO/IEC 9834-8:2008
、ISO/IEC 9834-8:2014 と改訂した。ISOの仕様はRFCを追いかけていて、基本的に同一である。

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

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

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

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

### バージョン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アドレスは人為的に差し替え可能であり、必ずしもあてにはできない。

ではバージョン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）となる。

### バージョン3/5
ドメイン名などなんらかの一意な名前（バイト列）を用いたUUIDで、ハッシュ関数としてMD5（バージョン3）またはSHA-1（バージョン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) を上書きする。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通り存在する。16進表記では、`RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRR`となる。バージョン4バリアント2のUUID（レガシーなGUID）の場合、バリアントに3ビットが確保されるため、UUIDの総数は半分になる。

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

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

128ビットの構成
# ミリ秒単位のUNIX時間を48ビット。10889年まで表現可能。
# バージョン。定数01112
# 乱数12ビット
# バリアント。定数102
# 乱数62ビット

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

### バージョン9から15
将来の使用のために予約。

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

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

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

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

クロスプラットフォームなプログラミング言語ではUUIDを生成したり文字列と相互変換したりするための機能が標準ライブラリとして用意されていることが多い。
* Java 1.5以降で実装された java.util.UUID。バージョン3と4が生成可能で、それ以外は外部ライブラリで生成する。
* Python の uuid
* .NET の Guid。名前は Guid だが UUID を扱える。
* C++では標準化されていないが、Boost C++ライブラリにはBoost.Uuidが存在する。
* Mac OS X 10.8およびiOS 6.0以降はObjective-C/Swiftから利用できる`UUID`および`NSUUID`クラスが実装されている。AppleのCore Foundationには`CFUUID`オブジェクト用のAPIが実装されている。

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

## 脚注

### 注釈

### 出典

## 関連項目
* 誕生日攻撃
* Object identifier (OID)
* Uniform Resource Identifier (URI)

## 外部リンク
*  - UUIDの仕様
* ISO/IEC 9834-8:2014