代表的な面接トピック

Unicode正規化とNFC、NFD、NFKC、NFKDをどのように説明しますか?

一般普通
Offer.cc 編集チーム公開日 更新日

質問

2つのユーザー名が一見同一に見えるにもかかわらず、システム内で異なると判定されます。Unicode正規化について説明し、NFC、NFD、NFKC、NFKDを比較した上で、それぞれをどのような場合に使用すべきか、または使用すべきでないかを述べてください。

プロンプトとコンテキスト

データベースの一意性チェック、検索、またはファイル名の比較において、2つの文字列が見た目は同一であるにもかかわらず異なると比較される場合があります。結合文字と合成済み文字、4つの形式、入力とストレージの境界、そしてなぜ正規化がケースフォールディング(case folding)、言語ルール、またはセキュリティポリシーの代わりにならないのかを説明してください。

面接官が見ているポイント

  • 正準等価性(canonical equivalence)と互換等価性(compatibility equivalence)を理解しているか。
  • ビジネスセマンティクスに基づいてNFC、NFD、NFKC、NFKDを選択できるか。
  • Unicodeのバージョン、データベースの照合順序(collation)、インデックス、サービス間の一貫性を考慮しているか。
  • 互換フォールディングによる情報損失のリスクを特定できるか。

回答前の明確化のための質問

そのフィールドが表示テキスト、ログイン識別子、検索キー、ファイル名、またはセキュリティ上機密な識別子のいずれであるかを確認します。言語、大文字小文字、Unicodeのバージョン、照合順序、そして元の入力を保持する必要があるかどうかを尋ねます。システムは元の入力を保持したまま、正規化された比較キーを別途保存することができます。

30秒の回答フレームワーク

Unicodeでは、1つの視覚的テキストに対して複数のコードポイントシーケンスが存在し得ます。NFCは正準分解の後に合成を行い、NFDは正準分解を行います。NFKCとNFKDは互換等価性も処理し、異なるフォーマットや意味的期待値を持つ文字をフォールディングする場合があります。NFCは一般的なテキストに対する標準的な選択肢であり、互換フォールディングには情報損失に対する明示的な許容が必要です。Unicodeのバージョンを固定し、正規化をケースフォールディング、スクリプトポリシー、セキュリティチェックとは分離して管理してください。

ステップごとの詳細解説

1. 正準等価性と合成

合成済み文字と、「基底文字+結合記号」は、見た目が同じで正準等価になり得ます。NFDはこれらを分解し、NFCは標準に従って合成します。正規化形式はべき等(idempotent)であり、再度適用しても文字列が変わり続けることはありません。

2. 互換等価性のコスト

NFKDは互換分解を行い、NFKCはその後に合成を行います。一部のフォント異体字、全角文字、装飾文字などが基底表現にマッピングされる場合があります。これは明示的に広範な検索や比較ポリシーを適用する場合に使用し、パスワード、法的文書、または外観を保持する必要があるコンテンツに対して自動的に使用してはなりません。

3. ストレージとセキュリティの境界

元の入力を保持し、バージョン管理された比較キーを生成します。一意性、トークン化、ケースフォールディング、およびスクリプト混同可能(confusable)文字のチェックを個別に定義します。ログイン名、ドメイン、権限識別子については、関連するプロトコルやセキュリティプロファイルに従ってください。NFKC単体では完全な防御にはなりません。

高品質な回答サンプル

私は表示用の値と比較用の値を分離します。Unicodeでは合成済み文字と結合シーケンスが同一の正準テキストを表すことができるため、コードポイントの単純比較では誤った不一致(false mismatch)が発生する可能性があります。NFDは分解し、NFCは再合成します。NFKDとNFKCは互換マッピングも適用するため、フォーマット情報が破棄される可能性があります。通常、一般的なテキストにはNFCを使用し、サポートするUnicodeバージョンを固定します。検索キーでは、その情報損失が意図的である場合に限り、ケースフォールディングや言語ルールとともにNFKCを使用することがあります。元の入力を保存し、データベースの一意性を確保するためにバージョン管理された正規化キーを追加で保存します。パスワード、署名、監査テキスト、セキュリティ識別子に対しては、プロトコルで規定されている場合を除き互換フォールディングを追加せず、指定された識別子チェックや混同可能文字チェックを適用します。テストでは、結合順序、繰り返しの正規化、多言語入力、バージョンアップグレード、照合順序の違いをカバーします。

よくある間違い

  • NFCとNFKCが等価であると述べること。
  • 正規化をケースフォールディング、翻字(transliteration)、またはアクセント記号の除去と同じものとして扱うこと。
  • すべてのフィールドにNFKCを適用し、互換文字の情報を失うこと。
  • データベースのインデックスやサービス間のバージョンを無視して、アプリケーション層でのみ正規化を行うこと。
  • 視覚的な類似性をセキュリティ上の同等性として扱い、スクリプト混同可能文字を見落とすこと。

フォローアップの質問と回答

なぜ正規化された文字列のみを保存しないのですか?

表示、監査、または法的な文脈において、元の入力が必要になる場合があります。両方を保持することで、ユーザーに影響を与える不可逆な変換を回避しつつ、安定した一意性チェックをサポートできます。

Unicodeバージョンのアップグレードによって一意性が損なわれることはありますか?

未割り当てのコードポイントや正規化データに影響を与える可能性があります。正規化バージョンを記録し、オフラインでキーを再計算し、衝突を確認した上で、インデックスを段階的に移行します。

正規化によってホモグラフ攻撃を防ぐことはできますか?

完全には防げません。正規化は定義された等価関係をカバーするだけです。セキュリティには、スクリプトの制限、混同可能文字の検出、プロトコルの識別子プロファイル、およびレビューも必要です。

公開情報ソース

関連する質問