きどたかのブログ

いつか誰かがこのブログからトラブルを解決しますように。

若手に宿題を出してみたよ IBM JDKの文字コード問題

2年目社員への挑戦状w


もともとx-IBM1399の文字化け調査をするために書いた簡易な検査コードを転用して、
すべての利用可能な文字コードに同じことを試したところ、出るわ出るわになった。
いつもなら自分の趣味としてPMRをオープンするんだが、
なんか職場にいる時間が短くなってるので任せてみようと。
自分はいちおうIBM Java6とJava6.0.1で試している。


java.nio.charsetを駆使。
本来なら合わせてio側も試すんだが、io側の検査コードは除去。
まあ、化けたら"?"になることのみを期待して、チェックしている。
IBM JDKの文字化けは普通は?になる。


国のジャンルで言うと3種類。


中国語
x-IBM1371
x-IBM1388


日本語
x-IBM1390
x-IBM1390A
x-IBM1399
x-IBM1399A


Unicode
UTF-16


中国語のx-IBM1388はクズ。目も当てられない。
sun.nio.cs.ext.IBM1388$Encoder.canEncode(CharSequence)は、
java.lang.UnsupportedOperationExceptionを投げてくる。ふざけんな。
その数、111万4112文字。
MIN_CODEPOINT=0,MAX_CODEPOINT=1114111だから、1文字もエンコード検査が出来ないw
中国の文字コードだから放置する。ちなみに簡体字EBCDICのようだよ。


中国語のx-IBM1371は1文字だけ問題があった。
これは?になる文字がいたのを検出した。
U+FFFD REPLACEMENT CHARACTER が?になる。
ちなみに繁体字EBCDICのようだよ。
これも中国語だから放置する。


UTF-16は104万8576文字の問題。
6万5536文字はOKなんだな。
65536って意味深な値でしょ。
そう、U+FFFFまではいいけど、U+10000から全部ダメってことよ。
ちなみにUTF-16javaが標準サポートする文字コードであり、
UTF-16BEとUTF-16LEでは問題が起きないのにUTF-16では問題がおこる。
日本語でいうと、第一水準とか第二水準が入ってるCJK統合漢字のブロックとかもダメ。
こんだけヒドイと世界規模。
UTF-16の問題は、encode(CharBuffer)がArrayIndexOutOfBoundsExceptionを投げてくること。
canEncode(CharSequence)でtrue返すくせに、encode(CharBuffer)でRuntimeException投げるとか鬼畜。


日本語の文字コードは以下の文字が?になる。
U+0303F
U+0FFE8
U+0FFE9
U+0FFEA
U+0FFEB
U+0FFEC
U+0FFED
U+0FFEE
全部記号で、しかも普通使わない文字なんだけど、
canEncode(CharSequence)でtrue返すのにencode(CharBuffer)すると化けるとか許せない。
ちなみにIBM1399やJIS X0213に見当たらない文字。(全角の矢印はあるが別のコードポイント)


ちなみに、OracleのJava7だと、サポートしてる文字コードが異なるので、
同じ事象が出るとは言えないのだが、(そもそも使えない文字コード
少なくともUTF-16のArrayIndexOutOfBoundsException問題は起きないことは言える。実験したからさ。