CP932 → UNICODE → CP932
はじめに
文字列を CP932 から UNICODE へ、UNICODE から CP932 へ変換する必要がしばしば生じますが、その変換テーブルは各々の言語やライブラリでかなり異なっています。
そこで、実際にどの程度異なっているのかをまず調査してみることにしました。
CP932 から UNICODE
- 最も問題なのはパッチを当てていない libiconv で、以下の6文字の変換が一般的ではありません。(パッチ: http://www2d.biglobe.ne.jp/~msyk/software/libiconv-patch.html)
- 8160→U+301C 〜
- 8161→U+2016 ‖
- 817C→U+2212 −
- 8191→U+00A2 ¢
- 8192→U+00A3 £
- 81CA→U+00AC ¬
- パッチを当てていない libiconv 以外では、次のような変換になります。
- 8160→U+FF5E 〜
- 8161→U+2225 ‖
- 817C→U+FF0D −
- 8191→U+FFE0 ¢
- 8192→U+FFE1 £
- 81CA→U+FFE2 ¬
- Windows と Perl と Python では 80→U+0080 という変換をしますが、Ruby, eglibc, glibc, Java, libiconv, apr-iconv では行いません。U+0080 は未定義の文字ですが Windows と OSX ではユーロのグリフが割り当てられています。
- Perl と Python では A0→U+F8F0, FD→U+F8F1, FE→U+F8F2, FF→U+F8F3 という、未定義の文字 4 文字を Private Use Area の文字へ変換しています。OSX ではこの 4 文字に括弧のようなグリフが割り当てられています。
- APR-iconv は CP932 の外字を Private Use Area の文字へ変換しません。
- Windows の MultiByteToWideChar() はなぜか 00 を U+0000 へ変換してくれません。
UNICODE から CP932
- Perl は Windows の WideCharToMultiByte() に WC_NO_BEST_FIT_CHARSフラグを渡したものと、完全に一致する変換をします。
- U+0000 から U+00FF までの変換は、変換を行うか行わないかの違いはありますが、各々の言語やライブラリで異なる文字へ変換されることはありません。
- Python は NEC 選定 IBM 拡張文字に含まれる IBM 拡張文字を、NEC 選定 IBM 拡張文字へ変換する傾向があります。
- パッチを当てていない iconv と APR-iconv は、NEC 特殊文字と IBM 拡張文字の両方に存在する文字を、IBM 拡張文字へ変換する傾向があります。
- APR-iconv は JIS X 0208 と NEC 特殊文字の両方に存在する文字をNEC 特殊文字へ変換する傾向があります。
- APR-iconv は Private Use Area の文字 を CP932 の外字へ変換しません。
- Windows と Perl と Python では U+F8F0→A0, U+F8F1→FD, U+F8F2→FE , U+F8F3→FF という、Private Use Area の文字を未定義の文字 4文字へ変換しています。OSX ではこの 4 文字に括弧のようなグリフが割り当てられています。
参考文献
- シフトJIS / EUC-JPとUnicodeとの妥当な変換表 http://www.nslabs.jp/round-trip.rhtml
- [PRB] SHIFT - JIS と Unicode 間の変換問題 http://support.microsoft.com/default.aspx?scid=kb;ja;JP170559
- libiconv-1.13-cp932.patch.gz http://www2d.biglobe.ne.jp/~msyk/software/libiconv-1.13-cp932-patch.html