IBM漢字コードからUTF8もしくは、SJISへの対応表が欲しかったので、ググったら、IBMのホームページでは提供を終了しているとのこと(IBM FAQ:漢字コード一覧表を入手したい)。
なので、Javaで作り出すことにした。
その結果作られた対応表はこちら。
IBM漢字=>UTF8:Cp930_UTF8.txt
[IBM漢字=>SJIS(Cp943C) Cp930_Cp943C.txt]
(https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp930_Cp943C.txt "https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp930_Cp943C.txt")
IBM漢字=>SJIS(Cp943C):Cp939_Cp943C.txt
IBM漢字=>UTF8:Cp939_UTF8.txt
IBM漢字=>UTF8やSJIS対応表のEXCEL
ポイントは、シフトコードで2バイト文字列をくくること。というかお約束。
シフトコードでくくるのは、2バイトのIBM漢字コードは、EBCDICの1バイトと区別がつかないからです。
もう少し具体的に書くと、シフトコード(シフトアウト(0x0e)2バイト文字の始まり、シフトイン(0x0f)2バイト文字の終わり)でくくられた内側のバイトコードをIBM漢字として扱うということです。
例えば、IBM漢字コード(0x4141)は"α"ですが、シフトコードでくくってからでないと意図した変換ができないので、次のようなイメージで変換します。
byte[] mc = new byte[4];
mc[0] = 0x0e; // シフトアウト
mc[1] = 0x41;
mc[2] = 0x41;
mc[3] = 0x0f; // シフトイン
String ibm = new String(mc, "Cp939");
こうやって作ったStringの1文字を変換先の文字コード(UTF8やCp943C)でバイト配列に変換してファイルに出力します。
os.write(ibm.getBytes("UTF8"));
IBM漢字コード:
Cp930: 4370 UDC 文字を含む日本語カタカナ漢字、5026 のスーパーセット。
Cp939: 4370 UDC 文字を含む日本語ラテン文字漢字、5035 のスーパーセット。
Shift-JIS(Shift-JISにはいくつか方言があるが、IBM系ということでCp943C:
Cp943: IBM OS/2 日本語、Cp932 および Shift-JIS のスーパーセット。
Cp943C: Cp943 の拡張。
コードイメージ:
public void makeIBMKanjiCodeTable(String fromCharsetName, String toCharsetName, OutputStream os) throws IOException {
if (fromCharsetName.equals("Cp930") || fromCharsetName.equals("Cp939")) {
;
} else {
throw new IOException("引数の変換元文字コードセットはCp930かCp939のいずれかを指定してください。:" + fromCharsetName);
}
if (toCharsetName.equals("UTF8") || toCharsetName.equals("Cp943C")) {
;
} else {
throw new IOException("引数の変換先文字コードセットはUTF8かCp943Cのいずれかを指定してください。:" + toCharsetName);
}
// 2バイトのIBM漢字コードをUTF8やCp943Cなどに変換するには、シフトコード(シフトアウト[0x0E]、シフトイン[0x0F])でくくってあげること。
byte[] mc = new byte[4];
mc[0] = 0x0e;
mc[3] = 0x0f;
// i:上位1byte
for (int i = 0x40; i <= 0xff; i++) {
mc[1] = (byte) i;
// j:下位1byte
for (int j = 0x40; j <= 0xff; j++) {
mc[2] = (byte) j;
// 0x40から0xffまでの2byteのmcをfromCharsetName(Cp930かCp939のIBM漢字コード)に変換する。
String ibm = new String(mc, fromCharsetName);
// 文字の変換ができない場合は,UTF-8で0xEFBFBDになっている。
// その時は、スペース1文字に置き換える。
if (Arrays.equals(CONVERSION_ERROR_CODE, ibm.getBytes("UTF-8"))) {
ibm = " ";
}
// ファイルに書き出すときの文字コード(toCharsetName)でエンコードして書き出す。
os.write(ibm.getBytes(toCharsetName));
os.write('\t');
// 改行0x0d0a
if (j == 0xff) {
os.write('\r');
os.write('\n');
}
}
}
}