日本語

開発者ツール · UUID ジェネレーター

UUID 文字列が整形式である理由と、チェッカーが認識できないこと

· 仕組み

uuid 暗号化 ブラウザ API

複数の UUID 表現を並べて表示: 正規の 8-4-4-4-12、大文字、中括弧付き、ハイフンなし、および urn 付き: プレフィックス
オリジナル ToolAcre ベクトル イラスト

大文字、中括弧、urn: 接頭辞、および欠落しているハイフンはすべて実際の入力で表示されます。この投稿では、正規形式を定義し、寛大なバリデータが何を受け入れるべきかを示し、整形式であることを存在から分離します。

404 であるべきだった 400 — UUID 検証がいかにずさんで混乱を招く API エラーを生成するか

API エンドポイントはクライアントから識別子を受け取ります: {12345678-90AB-CDEF-1234-567890ABCDEF}。検証コードは、/[0-9a-f]{32}/ と一致するかどうかをチェックし、無効であるとして拒否します。クライアントは、404 Not Found を意味する 400 Bad Request を受け取ります。識別子は整形式です (中括弧形式の有効な UUID です) が、バリデーターが厳密すぎます。逆に、32 文字の 16 進文字列 (ダッシュなし) を受け入れるエンドポイントは、123456789012345678901234567890123456 を受け入れ、有効なものとして解析し、タイプミスを見逃します。 RFC 9562 は正規のテキスト表現を定義していますが、実際の入力は 5 つの異なる形式で到着し、正規形式のみを受け入れるバリデーターは、意図された入力の 1 ~ 5 パーセントを拒否します。

正規のテキスト形式 — 8-4-4-4-12 の 32 小文字の 16 進数、標準で出力に指定されているとおり、正確には 36 文字

正規のテキスト形式は、ハイフンで区切られた 5 つのグループに分割された 32 小文字の 16 進数です: 8-4-4-4-12。 550e8400-e29b-41d4-a716-446655440000 として表されます。標準では出力に小文字を使用することが義務付けられています。入力時は、大文字と小文字を区別しない一致が推奨されます。この形式は明確であり、すべてのプラットフォームで同じ方法でバイトに解析され、すべての UUID ライブラリがデフォルトで出力するものです。 CSPRNG から新しい UUID を生成する場合、標準形式が生成する必要があり、ToolAcre が生成するものになります。現実世界の入力は、予測可能な方法で逸脱します。大文字の識別子 (550E8400-E29B-41D4-A716-446655440000) は、デフォルトで大文字が使用されるシステムでは一般的です。これらは同じバイトを表すため、小文字に正規化した後に受け入れられる必要があります。

実際に遭遇する亜種 — 大文字の 16 進数、{braces}、urn:uuid: プレフィックス、および 32 文字のハイフンなし形式。標準ではこれらを受け入れることが定められています。

中括弧形式 ({550e8400-e29b-41d4-a716-446655440000}) は、Python の uuid モジュールおよび Microsoft のシステムからの標準出力です。中括弧を削除すると、有効な標準形式が得られます。 URN プレフィックス (urn:uuid:550e8400-e29b-41d4-a716-446655440000) は、統一リソース名として RFC 8141 によって定義されています。スキームと識別子のプレフィックスを削除すると、正規形式が残ります。ハイフンのない形式 (550e8400e29b41d4a716446655440000) は、構造体のない 32 16 進数です。これは有効なバイトですが、バージョンとバリアントを読み取り可能にする 8-4-4-4-12 グループ化が失われます。これらのバリアントはすべて、同じ 128 ビット値にマップされます。 RFC 9562 セクション 3 では、入力時に大文字のバリアントを受け入れる必要があると述べています。他の変形を禁止するものではありません。出力時には正規の小文字形式を使用しなければならないと書かれています。

バージョンとバリアントの健全性 — 3 番目のグループが 0 で始まるか、4 番目のグループが f で始まる UUID を拒否するかどうか

整形式のバリデータは次のことを行う必要があります。 正規の 8-4-4-4-12 形式を小文字または大文字で受け入れる。 braced と urn: のバリアントを取り除き、コア フォームを検証することで受け入れます。ハイフンなしの 32 桁の 16 進文字列を受け入れ、比較のために正規としてフォーマットします。間違った数の 16 進数または 16 進数以外の文字を含む文字列を拒否します。最も一般的な間違いは、バリデーターが標準形式のみに一致するように手書きされたため、大文字または中括弧付きの入力を拒否することです。バージョンとバリアントの健全性チェックにより、タイプミスが見つかる可能性があります。 3 番目のグループが 0 または 9 で始まる場合、UUID は無効または予約されています。 4 番目のグループが e または f で始まる場合、そのバリアントは RFC 9562 ではありません。

実用的な例 — 6 つの候補文字列が厳格なチェックと緩やかなチェックを通過し、それぞれに合格または不合格の理由が付けられます。

寛大なバリデータはこれらの値を受け入れます。厳密なバリデーターはそれらを拒否することができます。 ToolAcre の整形式チェックでは、厳密な検証が実行されます。つまり、正しい位置にダッシュが含まれる正規の 36 文字形式が確認され、すべての位置の 16 進数が検証され、バージョンとバリアント ビットが範囲内にあるかどうかがチェックされます。 UUID がデータベースに存在するかどうか、または暗号的に安全なソースから生成されたかどうかはチェックしません。これらはアプリケーション ロジックによって実行される個別のチェックです。整った形は本物と同じではありません。その形状に従って正しく解析される UUID 文字列は、データベース内の行を識別しない可能性があります。

適切な形式は現実ではありません。なぜ構文的に完璧な UUID がデータに存在しないのか、そしてなぜチェッカーを認証層にしてはいけないのか

完全に形成された UUID は、推測されたか、間違ってコピー&ペーストされた可能性があります。形式の検証は最初の関門です。存在チェックと認可チェックは 2 番目と 3 番目です。フォーマットが無効な入力ごとにデータベースに対してルックアップを実行するのは無駄です。データベースクエリの前に形式が無効な入力を拒否することで時間を節約できます。 ToolAcre ジェネレーターは、標準の 36 文字の UUID を出力します。独自のバリデータを構築している場合は、データベースに問い合わせる前に、実際の入力と一致するように braced および urn: のバリアントを受け入れ、基本的な形状ルールに満たない文字列を拒否します。厳密なバリデータを実装するには、正規表現とエッジケースの処理が必要です。正規形式は単純です: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i (大文字と小文字は区別されません)。中括弧形式では中括弧が追加されます: /^\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}$/i. urn: バリアントではスキームが追加されます: /^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.

これでカバーされないもの — ストレージの ID の正規化と列タイプの選択は別個の決定です

すべてのバリアントを処理する単一の正規表現は、可読性は低くなりますが、可能です。ほとんどのバリデーターは最初に正規化を行い、中括弧と urn: プレフィックスを削除し、小文字に変換してから、正規のパターンと照合します。バージョンとバリアント ビットは、403 の記事で説明されているように、位置 14 と位置 19 を調べることで、パターン マッチング後に確認できます。無効な入力を適切に処理することは、検証設計の一部です。クライアントが不正な形式の UUID を送信する場合、エラー メッセージ内の正規表現パターンや内部検証ルールを公開しないでください。明確なエラーを返します: 「無効な UUID 形式です。期待される 8-4-4-4-12 形式 (550e8400-e29b-41d4-a716-446655440000 など)。」 試行しないでください。入力を修正するため。クライアントに再送信を依頼します。

要点: 形状を早期に検証し、存在を個別に検索します。ToolAcre チェックでは、データベースにアクセスする前にブラウザーで形状を確認します。

一部のシステムでは、セキュリティ監査 (注入の試みや形式混乱攻撃の検出) のために無効な入力がログに記録されます。 ToolAcre バリデーターは、明確なエラー メッセージを表示して非正規フォームを拒否し、自動修正を試みません。相互運用性にとって正規形式が重要である理由: あるシステムが UUID をハイフンなしの 16 進数として保存し、別のシステムが UUID を正規 8-4-4-4-12 として保存する場合、それらが等しいかどうかを比較するには正規化が必要です。大文字と小文字では、大文字と小文字を区別せずに比較する必要があります。固定具付きと裸の場合は、ストリップが必要です。これらの変動により、一括操作 (インポート、移行、比較) が難しくなります。正規形式を出力する標準ツールは摩擦を軽減します。 ToolAcre ジェネレーターは常に 36 文字の小文字正規形式を出力します。他のシステムから UUID をインポートする場合は、一貫性を確保するために ETL プロセスで UUID をこの形式に正規化してください。