2022-07-16
Unicodeと向き合う
Unicodeと向き合って3連休を費やしてしまいました。とりあえず書き記しておきます。
概要
- Unicodeの世界には制御文字や結合文字があるため、1文字が40バイトくらいに膨れ上がることがある。まずはこの事実を受け入れること。
- Unicodeを扱うには下記のような問題が生じるので、設計の際は気を付けること。
- 具体的な対策方法を書くには時間が足りなかった。
書記素クラスタ
- 「入力は10文字以内です」を正確に処理しているサイトは少ない。
- 文字数を正確にカウントするには「書記素クラスタ(Grapheme Cluster)」を数える。
- 数え方を誤っても、通常は増える(1文字が2文字扱いされる)ので案外平気。
- 文字を検索する機能を実装する場合も、書記素クラスタを考慮しなければならない。
正規化
- 「が」=「か」+「゛」のように、単一のコードポイントで表示できる文字を複数のコードポイントで表現してもよい。
- 互換性を高めるために、NFC方式でUnicode正規化するとよい。
- ただし、CJK互換漢字に分類されている旧字体(神)をNFCで正規化すると新字体(神)になる。
- 異体字セレクタが導入される前の文字なので、仕様だと割り切るのがいいかもしれない。
- NFKC方式でUnicode正規化すると、①や⒈のような文字を1に変換できる。こちらは検索エンジンのように、文字の形よりも意味を優先したい場合に使うとよい。
- 分解するときはNFD, NFKDを使う。
- NFDやNFKDはよく似た文字に分解するので、セキュリティに注意 (→Host/Split攻撃)
ToUpper/ToLower
- Unicode対応のToUpper, ToLowerは想定外の結果を生むので注意が必要。
- ß (ドイツ・エスツェット)の大文字は "SS"と2文字になる。
- i (トルコ)の大文字は İ で、 Iの小文字は ı である。
- Σ (ギリシャ・シグマ)の小文字は σだが、文末だとςである。
- 小文字のみが収録されている特殊文字は、大文字にすると複数のラテン文字に展開される。
- アカウントの乗っ取りのようなセキュリティリスクがある。
別の文字セットに変換する
- unicodeの文字集合の方が大きいので、変換に失敗するか、多対一の変換になる。例えばバックスラッシュと円マークの両方が円マークに変換される。この変換は不可逆変換である。