ものがたり(旧)

atsushieno.hatenablog.com に続く

doubts on Encoding.IsAlwaysNormalized()

.NET 2.0のSystem.Text.Encodingには、新しくIsAlwaysNormalized()というメソッドが追加されている。引数はNormalizationFormで、要はUAX#15 (Unicode Normalization)のNFD, NFC, NFKD, NFKCを表すenumだ。

Encodingクラスにこれが必要とされた理由は判然としないのだけど、要は、特定のエンコーディングで表現されうる文字から構成された文字列が、Unicode Normalizationを行わなくても常に(normalizeされた文字列という文脈での)同一性が担保されているか否か、を表すということなのだろう。

しかし、実装がいまいち信頼できない。

まず、僕が簡単に実験した範囲では、NormalizationFormがNFCでなければ、このメソッドは常にfalseを返す。また、.NET 2.0でサポートされているエンコーディングのうち、IsSingleByteがfalseであるものは常にfalseを返すようだ。

SBCS (IsSingleByte = true)の場合は、エンコーディングによってtrueだったりfalseだったりするようだ。

そこで、SBCSなのだから1バイト単位で変換されるはずだと考え、byte bytes = new byte {0, 1, 2 ... 254, 255}という配列を作成し、これをEncoding.GetString()で文字列sにして(その際、無効な文字はDecoderReplacementFallbackで空文字列に置き換える == スキップする)、その文字列をString.Normalize()した結果s2が、sと同一であるか否かで*1、IsAlwaysNormalized()の戻り値が決定されるべきであろう、と思ってやってみた。が、どうも想定結果と異なる(SAMEと表示される)エンコーディングがたくさんある。

何かもちっと別の検証方法があるんだろうか。

*1:単純にstring.IsNormalized()を使っても良いかもしれない