GUIDのバージョン解説:v1–v7の違いと選び方
2026-07-09
Tags: Windows · GUID · 解説 · QuickGUID
UUIDライブラリを開くと、uuid1()、uuid3()、uuid4()、uuid5()、そして最近は uuid7() も見えます。仕様は8つのバージョンを定義しています。実際にどれを使えばいいのでしょう?
短い答え:ほとんどはv4、データベースの主キーにはv7、同じ入力から常に同じGUIDが欲しい時はv5。 この記事の残りでその理由を説明します — バイト構成、各バージョンが存在する本当の理由、言語別のコードチートシートと一緒に。
GUID自体初めての方は、まず GUIDとは? で構造と一意性の基本を押さえてください。本記事はその技術版のコンパニオンで、各バージョンをさらに深く掘り下げます。
GUID/UUIDのバージョン一覧
各バージョンは同じ128ビットを埋める異なる レシピ です。バージョンのニブル(第3セグメントの最初の16進数字)が、どのレシピを使ったかを示します。
| バージョン | 生成元 | ソート可 | 典型的な用途 |
|---|---|---|---|
| v1 | 時刻 + MAC | はい | レガシーシステム(プライバシーリスク) |
| v2 | DCE Security | はい | 稀、特殊用途 |
| v3 | MD5名前空間ハッシュ | いいえ | 非推奨(v5を使用) |
| v4 | ランダム | いいえ | 汎用のデフォルト |
| v5 | SHA-1名前空間ハッシュ | いいえ | 決定的ID |
| v6 | 並べ替えたv1時刻 | はい | v1の直接置換 |
| v7 | ミリ秒タイムスタンプ | はい | DB主キー |
| v8 | ベンダー定義 | カスタム | 特殊用途 |
v1、v4、v5、v7で実運用の99%をカバーします。順に見ていきましょう。
v1:時刻とMACアドレス
v1はRFC 4122のオリジナルレシピです。3つのものを128ビットに詰め込みます:
| time_low (32) | time_mid (16) | ver+time_hi (16) | var+clk_seq (16) | node/MAC (48) |- 60ビットのタイムスタンプ — 1582-10-15(グレゴリオ暦採用日)からの100ナノ秒間隔。タイムスタンプは
time_low、time_mid、time_hiに分割されます。 - 14ビットのクロックシーケンス — 同じクロックティック内に生成された2つのGUIDや、システム時計が戻された場合を区別するカウンタ。
- 48ビットのノード — ネットワークカードのMACアドレス。
MACアドレスの問題
ノードフィールドは ハードウェアの指紋 です。公開するすべてのv1 GUIDはマシンのMACアドレスを運びます — そしてIPアドレスと違い、MACアドレスはグローバルに一意で永続的であることが前提です。これは現実のプライバシー漏洩です。
理論上の話ではありません。研究者は、ファイルのメタデータに埋め込まれたv1 GUIDを読むことで、ドキュメントを作成したマシンまで追跡できることを示しました。これが実証された後、Microsoft自身がOfficeのテレメトリからv1生成を削除しました。現代のOSも同じ理由でWi-Fiネットワークに提示するMACをランダム化しています。
結論: 新しいコードではv1を避けてください。レガシーシステム、COMインターフェース、一部のハードウェア寄りのツールに生き残っています — しかし今日自分で生成する理由はありません。
v2:DCE Security
v2は事実上決して出会うことのないバージョンです。v1の構成(タイムスタンプ + MAC)を引き継ぎ、その上に POSIX UID/GID — DCE(Distributed Computing Environment)セキュリティモデルのローカルユーザー識別子とグループ識別子 — を重ねて、UUIDが一意性と合わせてアクセス制御情報も運べるようにします。
v2はレガシーなエンタープライズシステムのDCE/RPC認証とACLのために存在します。明示的にDCE Securityを話すソフトウェアを保守しているのでなければ、v2を生成することも消費することもないでしょう。ここに載せたのは単にバージョン一覧を完全にするためと、いつかそのニブルに「2」を見かけた時に何を意味するのか悩まないようにするためです。
v3:非推奨になった理由
v3はSHA-1の代わりに MD5 を使う点を除いてv5と同じです。MD5には実用的な衝突攻撃があります — 異なる2つの入力を同じハッシュを生成するように細工できます。これは敵対的な環境でv3の決定性の保証を壊します。
RFC 4122は後方互換性のためにv3を残しましたが、v5がそれに取って代わりました。今日v3を生成する理由はありません。実地でv3に出会ったら、レガシーとして扱ってください。
v4:ランダムのデフォルト
v4はほぼすべての「GUID生成」呼び出し [guid]::NewGuid()、Guid.NewGuid()、crypto.randomUUID()、uuid.uuid4()、NEWID() が返すものです。128ビットのうち122ビットを暗号論的に強い乱数で埋めます(残り6ビットはバージョンとバリアントのマーカー)。
タイムスタンプなし、MACなし、マシン状態なし — 純粋な乱数。これによりv4は公開しても安全で、並列化が自明で、現実的などんな負荷でも衝突耐性が十分です。衝突の完全な計算(そして「10億年」という拡散された主張が誕生日パラドックスを誤解している理由)は ハブ記事 を参照してください。
結論: これがデフォルトです。特別な理由がない限りv4を選んでください。
v5:決定的な名前空間ID
これは多くの開発者が名前は知っているものの実際には使ったことのないバージョンです — そして本物の有用な問題を解決します。
v5を使うと 同じ 入力から毎回 同じ GUIDを導出できます。名前空間UUIDと名前文字列を渡すと、決定的な識別子を返します:
import uuid
# 同じ入力 → 同じGUID、毎回の実行、どのマシンでも
dns_guid = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
url_guid = uuid.uuid5(uuid.NAMESPACE_URL, 'https://prunelab.net/blog/guid-explained')
print(dns_guid) # 常に cf14e0a3-...(同じ値)
print(dns_guid == uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')) # True仕組み
内部では、v5は名前空間UUIDのバイトと名前のUTF-8バイトを連結し、結果にSHA-1を実行し、最初の16バイトを取り、それからバージョン(5)とバリアントのビットを刻印します。名前空間自体がUUIDです — NAMESPACE_DNS、NAMESPACE_URL、NAMESPACE_OID、NAMESPACE_X500 は定義済みですが、任意のUUIDを名前空間として使えます。
v5が適切な道具の時
- 再現可能なテストフィクスチャ — 実行間で安定するテストデータのIDを生成し、失敗したテストが常に同じエンティティを指すようにする。
- URL由来の識別子 — データベース検索なしでURLをGUIDに変換。同じURLに対し独立して
uuid5(NAMESPACE_URL, url)を計算する2つのシステムは常に一致する。 - 冪等な重複排除 — 同じレコードを2回インポートするとGUIDは自分自身と衝突するので、キーだけで重複を検出できる。
v4との決定的な対比:v4は呼び出しごとに一意の値を返す(同じ入力でも);v5は同じ入力に対し安定した値を返す。両者は交換可能ではありません。
結論: 入力文字列から 再現可能に 導出されるGUIDが必要な時はいつもv5を使ってください。
v6:おそらく不要なv1の修正
v6はv1と全く同じデータ — 同じタイムスタンプ、同じクロックシーケンスとMAC — を含みますが、値が自然に時系列でソートされるようにタイムスタンプのビットを再編成します。v1ではタイムスタンプは不格好に分割(low、mid、high)されていますが、v6ではhigh-firstに格納され、文字列の辞書式ソートが時間ソートと一致します。
v6は2024年にv7と共に RFC 9562 で標準化されました。主にv1の時計とMACのモデルに縛られたシステム向けの 直接移行パス として存在します:既存のタイムスタンプロジックを保ったまま、ビット配置だけを書き直せます。
新しいシステムでは v7がほぼ常に良い選択です。 v7はミリ秒タイムスタンプ(v1/v6の100ナノ秒グレゴリオ計算より単純)を使い、MACアドレスを埋め込まず、よりクリーンな乱数充填を持ちます。v6は「生成モデルを変えずにv1をどう近代化するか」に答え、v7は「今後何を使うべきか」に答えます。
v7:データベース向けの時間順序
v7はv4以来最重要の新追加です。v4がデータベースで作る問題を解決します。
データベースでのv4の問題
データベースがGUIDを主キーに使うとき、そのキーはB+木インデックスを支えます。B+木は挿入が概ね順序付けられている時に効率的に保たれます — 新しい値は右端に着て既存のページを埋めます。ランダムなv4 GUIDはキー空間全体に散らばるので、挿入のたびにランダムなページを叩きます。大きなテーブルではこれが絶え間ないページ分割、インデックスの断片化、キャッシュスラッシュ、書き込み増幅を引き起こします。SQL Serverの解決策(NEWSEQUENTIALID())は、シーケンス情報を漏らす独自仕様で移植性のないハックです。
v7の構成
| unix_ts_ms (48) | ver (4) | rand_a (12) | var (2) | rand_b (62) |- 48ビットのミリ秒Unixタイムスタンプ — 先頭フィールドなので、値は時間と共に増加します。
- 4ビットのバージョン —
7に設定。 - 12ビットの rand_a — ランダム、または同じミリ秒内で順序付ける単調カウンタとしてオプション使用。
- 2ビットのバリアント — 標準のRFC 9562マーカー。
- 62ビットの rand_b — ランダム。
タイムスタンプが先頭なので、連続して生成されたv7 GUIDは自然に順序付けられます:インデックス挿入は右端に集まり、ページは綺麗に埋まり、B+木は自動採番整数の時のように振る舞います — それでいて中央の調整機関なしでグローバルに一意です。
v7が価値を持たない時
- インメモリストア(Redis、memcached)— B+木なし、断片化コストなし。v4で十分。
- 小さなテーブル — 数百万行未満ではv4とv7の差は見えません。
- 非キー列 — GUIDが格納された属性であってインデックスキーでない場合、順序は無関係です。
- 不透明であるべきGUID — v7は生成ミリ秒を漏らし、セキュリティ上敏感な文脈では望ましくない可能性があります。
結論: GUIDが本物のデータベースのクラスタ化主キーならv7を使ってください。それ以外はv4。
v8:ベンダー定義
v8は非常口です:RFC 9562は、バージョンのニブルが 8 でバリアントビットが正しければ、あとはベンダーが独自のビット構成を定義することを許します。それ以外のすべて — タイムスタンプの幅、乱数源、エンコーディング — は実装者次第です。
v8を見るのは、何か特別な理由で独自のUUIDスキームを設計したシステム(例えばルーティング用にシャードIDやノードIDをUUIDに焼き込むなど)だけでしょう。そういうシステムを構築しているのでなければv8は無関係ですし、構築しているとしても、ルールはこの記事の内容ではなく、あなた自身のスキームが定義するものです。
実際にどのバージョンを使うべき?
意思決定ガイド:
- 「汎用のIDを生成?」 → v4。 90%の場面の答えです。
- 「DB主キー、または時間順序が必要?」 → v7。 特に大きなテーブルのクラスタ化インデックスで。
- 「同じ入力に毎回同じGUIDが必要?」 → v5。 文字列からの決定的マッピング。
- 「v1を期待するレガシーシステムと作業中?」 → v1(互換性を維持)、ただしv7への移行を計画。
- 「v3を使えと言われた?」 → やめて。代わりに v5 を(v3のMD5は壊れています)。
- 「最新のものが欲しい。」 → それは理由になりません。v7は新しく かつ 本物の問題(DB順序)を解決します;v6は新しく かつ 主にv1移行の補助です。新しさではなくユースケースで選んでください。
まだ迷うならv4を使ってください。デフォルトには理由があります。
バージョンと言語別のGUID生成
| 言語 / ツール | v4(デフォルト) | v5(決定的) | v7(順序付き) |
|---|---|---|---|
| PowerShell | [guid]::NewGuid() | — | — |
| C# / .NET | Guid.NewGuid() | — | Guid.CreateVersion7() (.NET 9+) |
| Python | uuid.uuid4() | uuid.uuid5(uuid.NAMESPACE_URL, 'name') | uuid.uuid7() (3.14 beta) / ライブラリ |
| JavaScript | crypto.randomUUID() | — | (npm uuid v11+) |
| Node.js (uuidライブラリ) | uuid.v4() | uuid.v5('name', NAMESPACE) | uuid.v7() |
| SQL Server | NEWID() | — | — |
| PostgreSQL | gen_random_uuid() | — | (拡張) |
いくつかの注意:標準ライブラリへのv7のネイティブサポートは2026年時点でまだ届きつつあります。Node.jsの uuid パッケージ(v11+)と.NET 9がネイティブで提供し、Pythonは3.14で uuid.uuid7() を追加します;古いランタイムにはライブラリが必要です。v5のサポートはほぼ普遍的で、エントロピー源を必要としない純粋なSHA-1の計算だからです。
よくある質問
v7はv4に代わるデフォルトになりますか?
いいえ。v4が汎用デフォルトのままです。v7が勝つのはGUIDが順序付き主キーの時だけです — 他のほとんどの用途(セッショントークン、リクエストID、コンテンツハッシュ、DB以外のすべて)ではv4のランダム性は欠点ではなく、v7の先頭タイムスタンプは利益なくタイミング情報を漏らすだけです。
v1はまだ安全に使えますか?
いいえ。v1はネットワークカードのMACアドレスを埋め込みます — 永続的なハードウェアの指紋です。研究者がドキュメントの埋め込まれたGUID経由でマシンを追跡した後、Microsoft自身がOfficeのテレメトリからv1を削除しました。新しいコードではv1を完全に避けてください;レガシーのv1にはv7への移行を計画してください。
v3とv5の違いは?
両方とも決定的な名前空間ハッシュです(同じ入力 → 同じGUID)。v3はMD5、v5はSHA-1を使います。MD5には実用的な衝突攻撃があるため、v3は完全性目的では壊れていると見なされ、v5に置き換えられました。今日v3を生成する理由はありません。
v4のGUIDをv7に変換できますか?
いいえ。バージョンは入れ替えられるラベルではなく — 各バージョンは全く異なる生成ロジックを使います。v4には抽出するタイムスタンプがないので、「v7を得る」唯一の方法は新しいものを生成することです。v4の主キー列をv7に移行する必要があるなら、実際には新しい列を追加して書き直すことになります。
.NETはv7をネイティブでサポートしますか?
はい。Guid.CreateVersion7() は .NET 9(2024年11月リリース)で追加されました。.NET 8以前の場合は、NuGetパッケージ GenVault や UUIDv7 を使うか、アップグレードしてください。
QuickGUID:v4・v7を生成、任意の形式に変換
日常のGUID作業には、QuickGUID がフルワークフローをカバーするWindowsネイティブのツールボックスです:
- バッチ生成 v4またはv7、一度に最大1,000件
- 10+形式変換:標準、ハイフンなし、中括弧、Base64、Cバイト配列、
DEFINE_GUIDマクロ — すべてライブプレビュー付き - スマート抽出:ログやソースコードを貼り付け、すべてのGUIDを自動で見つけて変換
- ライブデコレータ:引用符、接頭辞/接尾辞、大文字/小文字 — グローバルに切り替えてそのままコピー
完全無料、100%オフライン。
最後に
バージョンシステムが存在するのは、異なる仕事が異なる保証を必要とするからです:v4は追跡不能なランダム性、v5は再現性、v7は順序性を与えます。デフォルトでv4、データベースキーではv7、同じ入力に同じGUIDが必要な時はv5を使ってください。
GUIDは初めてですか? まず GUIDとは? で構造、ハイフン形式、実践で衝突を問題外にするのに128ビットで十分な理由の基本を押さえてください。