開発者ツール · UUID ジェネレーター
128 ビットから 36 文字へ: UUID テキスト エンコーディングの仕組み
· 仕組み
uuid 暗号化 ブラウザ API
UUID は 16 バイトですが、よく知られた形式は 36 文字です。この記事では、16 進数の倍加、ハイフン、大文字と小文字の規則、および標準形式が長すぎる場合に使用する短いエンコーディングについて説明します。
列の幅が値より広い理由 — テキスト内の 36 文字に相当する 16 バイト値と、それが URL とストレージに与える影響
UUID 形式を選択すると、ストレージ列の幅が爆発的に増加します。 128 ビット値は 16 バイトですが、そのテキスト表現はエンコードによって異なります: 16 進数 (ハイフン付きの 36 文字、ハイフンなしの 32 文字)、base64url (22 文字)、base58 (22–23 文字)、 Crockford Base32 (26 文字)。スキーマが UUID を VARCHAR(36) として保存する場合、すべての行で 36 文字を消費することになります。 1 億行があり、他の列がないテーブルでは、バイナリの 16 ギガバイトと比較して、テキスト オーバーヘッドが 36 ギガバイトになります。この選択は見た目だけの問題ではありません。クエリのサイズ、ネットワークのラウンドトリップ、キャッシュの圧力に影響します。正規の形式は 36 文字です: 8 桁の 16 進数、ハイフン、4 つの 16 進数、ハイフン、4 つの 16 進数、ハイフン、4 つの 16 進数、ハイフン、12 桁の 16 進数。
16 進数はすべてを 2 倍にします。各バイトは 2 文字になり、4 つのハイフンで 36 が完成します。
各バイトはちょうど 2 つの 16 進文字 (0 ~ 9、a ~ f) になります。ハイフンは、読みやすさと、UUID が最初に指定されたときからのレガシーの理由から存在します。 16 進エンコードではバイト数が 2 倍になります。16 バイトは、32 の 16 進数と 4 ハイフンになります。これは最も遅く、最も長いエンコードですが、人間が判読可能であり、どこでもサポートされています。大文字と小文字の規則: RFC 9562 では、正規の出力では小文字を使用することが義務付けられていますが、入力では大文字と小文字が区別されません。大文字を保存すると正規化の機会が無駄になるため、小文字を保存し、入力時に大文字と小文字を区別せずに比較します。 Base64url エンコードでは、64 文字のアルファベット (A ~ Z、a ~ z、0 ~ 9、マイナス、アンダースコア) を使用して 3 バイトを 4 文字として表します。 16 バイトは 21 文字と 1 つのパディング文字となり、合計 22 文字になります。 Base64url は、URL で予約されているパディングと標準文字 (プラスとスラッシュ) を削除します。
大文字と小文字の規則 - 出力では小文字、入力では大文字と小文字が区別されない、および大文字と小文字が混合した比較によってサイレント不一致が発生する理由
Base64url 形式の UUID は、16 進数と比較して 14 文字を節約し、パーセント エンコーディングのない URL で有効です。トレードオフ: 読みにくくなります (小文字は数字のように見えます。b、8、B、および 8 は混同しやすいです)。 Base58 はビットコインやその他のブロックチェーンで使用され、あいまいな文字 (0、O、I、l) を削除し、読み取り可能な状態を保ちながら結果の 22 ~ 23 文字を作成します。 Crockford Base32 (チェックサム付き ISBN のような形式用に設計) は 26 文字を使用し、簡潔さよりも正確さを優先します。 Microsoft GUID バイトオーダー トラップは、一部のデータベースの UUID ストレージに適用されます。 RFC 9562 は、すべてのバイトのネットワーク バイト オーダー (ビッグ エンディアン) を指定します。一部の Microsoft SQL Server 構成では、最初の 3 つのフィールドにリトル エンディアンのバイト順で GUID が格納されます。
より短いエンコード — 22 文字の Base64url、base58 および Crockford Base32 (読みやすさとコピー&ペーストの安全性はトレードオフになります)
ビッグエンディアンとリトルエンディアンに格納された同じ 128 ビット値は、異なる 16 進文字列を生成します。 Microsoft GUID として保存された UUID 550e8400-e29b-41d4-a716-446655440000 は、00840e55-9be2-d441-a716-446655440000 (バイト 0–3 および4 – 5 および 6 – 7 は逆になります)。システムが RFC 準拠システムと Microsoft システムの間のブリッジを行う場合は、このことを認識し、境界で正規化するか、各列で使用している形式を文書化する必要があります。動作した例: v4 UUID 9b2e4f1a-4f3e-4c1a-8a7d-1b2c3d4e5f60 (16 進数) は 36 文字を占めます。 16 バイトとしては、9b 2e 4f 1a 4f 3e 4c 1a 8a 7d 1b 2c 3d 4e 5f 60 になります。 Base64URL の場合: 3 バイトのチャンクに分割し、Base64 に変換し、パディングを削除します: my5PGk8-TBqKfRssPTRPX2A。ハイフンなしの 16 進数: 9b2e4f1a4f3e4c1a8a7d1b2c3d4e5f60 (32 文字)。
Microsoft バイトオーダー トラップ — GUID の最初の 3 つのフィールドがリトル エンディアンで格納され、同じバイトが 2 つの異なる文字列として印刷される方法
Base64url は 14 文字を保存します。 Base58 ではほぼ同じように保存されます。 16進数が標準です。ユースケースに基づいて選択してください。識別子が URL に表示され、すべての文字が重要な場合は、base64url を使用します。人間が読むログや UI に表示される場合は、16 進正規形式を使用します。チェックサムが重要なブロックチェーン システムまたは分散システムを構築している場合は、base58 または Crockford Base32 を使用してください。列のタイプを選択するときは、実際のアクセス パターンに最適化する値を保存します。 UUID を頻繁にクエリし、大文字と小文字を区別しない一致が必要な場合は、binary(16) を保存し、データベースに表現を処理させます。部分文字列でクエリを実行する場合 (プレフィックスで始まる UUID を検索する場合)、デバッグ出力では 16 進数の方が読みやすくなります。
実用的な例 — バイト、正規の 16 進数、および短縮形式で記述された 1 つの識別子、各変換ステップを示す
CSV にエクスポートして技術者以外のユーザーに電子メールを送信する場合は、16 進数の方が認識しやすくなります。スペースに制約がある場合 (ローカル キャッシュのあるモバイル アプリの場合)、base64url または Base58 によって帯域幅が節約されます。 ToolAcre ジェネレーターは、正規の 36 文字の 16 進形式を出力します。別のエンコーディングが必要な場合でも、形式をチェックする前に有効な表現を正規化するため、整形式チェックは引き続き機能します。数百万の UUID をエンコードまたはデコードする場合、パフォーマンスに関する考慮事項が重要になります。 16 進エンコードは単純です。各バイトを 2 文字に変換するのにかかる時間は 1 バイトあたり O(1) です。デコードも同様に簡単です。 Base64 エンコードとデコードはルックアップ テーブルを使用するため、若干遅くなります (ハードウェアと実装に応じて、バイトあたり 16 進数よりもおよそ 2 ~ 3 倍遅くなります)。 Base58 は本質的に基数変換であり、モジュラー演算を必要とするため、大幅に遅くなります。
これでカバーされないもの — ネイティブ UUID タイプとバイナリ (16) などのデータベース列の選択については、個別に説明します
システムがホット ループ (高頻度の識別子の生成、一括エクスポート) で UUID をエンコードまたはデコードする場合、16 進数の方が高速です。エンコードが頻繁に行われず、14 文字の節約が重要な場合は、base64url が合理的なトレードオフです。 ToolAcre ジェネレーターは 16 進数を出力するため、互換性を犠牲にすることなくパフォーマンスの利点が得られます。文字列比較のセマンティクスはエンコーディングによって異なります。 16 進数の UUID は文字列として比較できます: 550e8400-e29b-41d4-a716-446655440000 < 550e8400-e29b-41d4-a716-446655440001 (辞書編集的な比較は機能します)。バイナリ UUID はバイトとして比較できます。バイトごとの比較は数値比較と同じです。ただし、Base64url および Base58 でエンコードされた UUID は、辞書編集文字列比較において数値の順序を保持しません。システムが UUID の辞書編集的ソート (インデックスまたはデータベース キーを構築するための驚くほど一般的なパターン) に依存している場合は、16 進数、バイナリ、またはソート可能な UUID バリアント (v6 または v7) のいずれかを使用する必要があります。
要点: 境界では正規形式を維持します。ToolAcre ジェネレーターは標準の 36 文字 UUID を出力し、そのチェックはその形式の文字列を受け入れます。
ToolAcre ジェネレーターは現在 v4 UUID を生成しますが、エンコード順序で並べ替えることはできません。相互運用性を実現するには、単一のエンコーディングの標準化が必要です。 hex、base64、およびbase58のUUIDを同時に受け入れるシステムは、処理前にすべての入力を正規形式に正規化する必要があります。これは可能ですが、複雑さが増します。外部 API またはデータベースには特定のエンコーディングが必要な場合があります。一部の API は urn:uuid: プレフィックス付き 16 進数を想定し、その他の API はハイフンなしの 16 進数を想定し、さらに他の API は Base64url を想定します。システムの UUID エンコードの期待を API コントラクトに明確に文書化します。 ToolAcre ジェネレーターは常に正規の 16 進数を出力します。他のエンコーディングが必要な場合は、変換を明示的に実行し、トレードオフ (スペース、パフォーマンス、読みやすさ、並べ替えやすさ) をチームに文書化してください。