IBM漢字コードからUTF8やSJISに変換する表を手に入れたい→手に入れた

IBM漢字コードからUTF8もしくは、SJISへの対応表が欲しかったので、ググったら、IBMのホームページでは提供を終了しているとのこと([IBM FAQ:漢字コード一覧表を入手したい](http://www-06.ibm.com/jp/domino02/services/dialqa/cicfaq.nsf/All/t0027E983 "http://www-06.ibm.com/jp/domino02/services/dialqa/cicfaq.nsf/All/t0027E983"))。

なので、Javaで作り出すことにした。
その結果作られた対応表はこちら。
[IBM漢字＝＞UTF8:Cp930_UTF8.txt](https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp930_UTF8.txt "https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/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](https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp939_Cp943C.txt "https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp939_Cp943C.txt")
[IBM漢字＝＞UTF8:Cp939_UTF8.txt](https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp939_UTF8.txt "https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/Cp939_UTF8.txt")
[IBM漢字＝＞UTF8やSJIS対応表のEXCEL](https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/IBM%E6%BC%A2%E5%AD%97-UTF8SJIS%E5%AF%BE%E5%BF%9C%E8%A1%A8.xlsx "https://github.com/madilloar/pub-pages/blob/master/docs/ibm-kanji/IBM%E6%BC%A2%E5%AD%97-UTF8SJIS%E5%AF%BE%E5%BF%9C%E8%A1%A8.xlsx")


ポイントは、シフトコードで2バイト文字列をくくること。というかお約束。
シフトコードでくくるのは、2バイトのIBM漢字コードは、EBCDICの1バイトと区別がつかないからです。

もう少し具体的に書くと、シフトコード(シフトアウト(0x0e)2バイト文字の始まり、シフトイン(0x0f)2バイト文字の終わり)でくくられた内側のバイトコードをIBM漢字として扱うということです。

例えば、IBM漢字コード(0x4141)は"α"ですが、シフトコードでくくってからでないと意図した変換ができないので、次のようなイメージで変換します。

```java:断片その１：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)でバイト配列に変換してファイルに出力します。

```java:断片その２:変換先の文字コードセットで出力
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 の拡張。

**コードイメージ:**

```java:DoublebyteCharcode.java
  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');
        }
      }
    }
  }
```