cp943CのCharsetで、全角ダッシュが1バイト文字判定されてしまうんだけど… という話を聞きました。
「あ、波ダッシュ問題で見たやつだ!」
と思うのですが、Charsetをms932に変えると、どういう影響があるんだ!ということを知りたいということだったので調べてみました。
文字の一覧を、cp943cとms932の両方でgetBytesして、違いを比較すればよいわけです。文字の一覧はコードポイントからStringに変換すればOKです。
(defn to-hex-str [bs]
(let [sb (StringBuilder. 8)]
(doseq [b bs]
(.append sb (Integer/toHexString (bit-and (bit-shift-right b 4) 0xF)))
(.append sb (Integer/toHexString (bit-and b 0xF))))
(.toString sb)))
(doseq [i (range 32 65536)]
(let [ch (String. (into-array Integer/TYPE [i]) 0 1)
ch-ms932 (vec (.getBytes ch "ms932"))
ch-cp943c (vec (.getBytes ch "cp943c"))]
(if (not= ch-ms932 ch-cp943c)
(println ch (format "%x" i) (to-hex-str ch-ms932) (to-hex-str ch-cp943c)))))
実行してみると、こうなります。
文字 コードポイント ms932 cp943c
¢ a2 8191 3f
£ a3 8192 3f
¦ a6 3f fa55
« ab 81e1 3f
¬ ac 81ca 3f
¯ af 8150 3f
µ b5 83ca 3f
· b7 8145 3f
¸ b8 8143 3f
» bb 81e2 3f
— 2014 3f 815c
― 2015 815c 3f
‖ 2016 3f 8161
№ 2116 8782 fa59
℡ 2121 8784 fa5a
Ⅰ 2160 8754 fa4a
Ⅱ 2161 8755 fa4b
Ⅲ 2162 8756 fa4c
Ⅳ 2163 8757 fa4d
Ⅴ 2164 8758 fa4e
Ⅵ 2165 8759 fa4f
Ⅶ 2166 875a fa50
Ⅷ 2167 875b fa51
Ⅸ 2168 875c fa52
Ⅹ 2169 875d fa53
− 2212 3f 817c
∥ 2225 8161 3f
〜 301c 3f 8160
ゔ 3094 8394 3f
㈱ 3231 878a fa58
- ff0d 817c 3f
~ ff5e 8160 3f
¦ ffe4 fa55 3f
3fになっているところが、そのCharsetでは対応する文字がない、ということを示しています。
波ダッシュ問題も一目瞭然ですね。つまり、今回の話はコードポイント0x2015の全角ダッシュが入力されて、cp943CでgetBytesされたものと想定されます。
cp943Cは微妙に代替文字が無いのが気になります…