2017年01月08日

文字コード

あんまり仕事の内容を詳しく書くことはできないのですけど、なんだかおもしろいなーって思ってるのがJavaの日本語メールでの文字コードです。

その前に、簡単に僕がどう理解しているかを書きます。

Javaでは、UTF-16で値を持ってます。でも、ファイルを読んだり、情報を送信するときに別の文字コードが使われてることが多いわけです。

そうすると、読むファイルがEUC-JPで書かれてるよーとか、送信するときにJISで送ってねーとか、そういう場合に、文字コードを指定してあげます。

読むファイルがEUC-JPだよと指定した場合、データーを読んだらJavaはEUC-JPからUTF-16に変換して保持するわけです。

逆に送信する際にJISだよと指定していれば、UTF-16からJISに変換して送るわけです。

さて、UTF-16で保持している情報に対して、JISではどういうバイト列になっているのかなというのを知りたいとき、StringクラスのgetBytes()メソッドを使います。

String str = "あ";
byte[] bytes = str.getBytes("JIS");
これでバイトの配列が取れます。

そして、String str2 = new String(str, "JIS");
とすると、元のStringの値が作れます。

で、この部分を
String str2 = new String(str);
とも書けるんですが、その場合、文字コードはデフォルトの文字コードが適用されます。システムプロパティのfile.encodingっていうやつ。

でなんか、上で書いたようなのが実際に使われてて、それが、開発時はMS932、運用時はEUC-JP、そして今回UTF-8になります。

つまり、new String(str)は、元の文字にならないんです。

なんなの?これ。。

でここからは、もう解説しません。わからないから。ただ、こうなってんのかーと確認できるコードだけ載せておきます。もしかしたら興味ある人がいるかもだし。

import java.io.UnsupportedEncodingException;

public class Test2 {
public static void main(String[] args) throws UnsupportedEncodingException {
// TODO Auto-generated method stub
String str = "あ";
byte[] bytes3 = str.getBytes("MS932");
print("MS932 bytes",bytes3);
bytes3 = str.getBytes("UTF-8");
print("UTF-8 bytes",bytes3);
bytes3 = str.getBytes("UTF-16");
print("UTF-16 bytes",bytes3);

byte[] bytes = str.getBytes("JIS");
String back = new String(bytes, "JIS");
//System.out.println(back);
print("JIS bytes",bytes);

back = new String(bytes, "UTF-8");
byte[] bytes2 = back.getBytes("UTF-8");
print("JIS bytes -> encode by UTF-8 -> UTF-8 bytes",bytes2);

back = new String(bytes, "UTF-16");
bytes2 = back.getBytes("UTF-16");
print("JIS bytes -> encode by UTF-16 -> UTF-16 bytes",bytes2);

back = new String(bytes, "UTF-8");
bytes2 = back.getBytes("JIS");
print("JIS bytes -> encode by UTF-8 -> JIS bytes",bytes2);

back = new String(bytes, "MS932");
bytes2 = back.getBytes("JIS");
print("JIS bytes -> encode by MS932 -> JIS bytes",bytes2);

back = new String(bytes, "EUC-JP");
bytes2 = back.getBytes("JIS");
print("JIS bytes -> encode by EUC-JP -> JIS bytes",bytes2);

back = new String(bytes, "UTF-16");
bytes2 = back.getBytes("JIS");
print("JIS bytes -> encode by UTF-16 -> JIS bytes",bytes2);
}

static void print(String msg, byte[] bytes) {
System.out.println("--------");
System.out.println("--"+msg);
System.out.println(bytes.length+" bytes");
for(byte b:bytes) {
System.out.printf("%02x", b);
}
System.out.println("\r\n");
}
}


そして、結果はこれ。
--------
--MS932 bytes
2 bytes
82a0

--------
--UTF-8 bytes
3 bytes
e38182

--------
--UTF-16 bytes
4 bytes
feff3042

--------
--JIS bytes
8 bytes
1b244224221b2842

--------
--JIS bytes -> encode by UTF-8 -> UTF-8 bytes
8 bytes
1b244224221b2842

--------
--JIS bytes -> encode by UTF-16 -> UTF-16 bytes
10 bytes
feff1b244224221b2842

--------
--JIS bytes -> encode by UTF-8 -> JIS bytes
8 bytes
1b244224221b2842

--------
--JIS bytes -> encode by MS932 -> JIS bytes
8 bytes
1b244224221b2842

--------
--JIS bytes -> encode by EUC-JP -> JIS bytes
8 bytes
1b244224221b2842

--------
--JIS bytes -> encode by UTF-16 -> JIS bytes
14 bytes
1b244221292129212921291b2842


もしかしてJISってどの文字コードとも互換性というかなんかわかんないことがあるのかなー(同じ文字だということではなく、バイト配列が存在するという意味)、と思ったんですが、もう追うのはやめようと思います。僕の想像が当たってるとすると、なんだか偶然うまくいってるだけのような気がするので。

file.encodingをUTF-16に変えてみたらきちんと動かないってことかもねぇ。そういう環境ってあるのかなぁぁ。。これは試してみよう。

非常にお世話になったサイトがこちら。
http://d.hatena.ne.jp/cero-t/20110621

これはほんとなのか?と思ったサイト。
https://allabout.co.jp/gm/gc/80616/2/
タイトルと本文メッセージのテキストをISO-2022JPに変換したStringを取得しているわけです。

っていうところ。端折って書いただけかもしれないし、本当なのかもしれないけど。

誰か解説してくれないかなー。

<追記>
結局のところ、JISって3バイトずつのエスケープシーケンスに囲まれた2バイト文字になってて、1bがESCとか、24が$とか、42がBとか、MS932でもEUC-JPでもUTF-8でも必ずマップできるってことで、それはUS-ASCIIでも同じだし、ってことみたい。。
http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html

以上

blog_icon.png
posted by はたけきかく at 19:50 | Comment(0) | 日記 | このブログの読者になる | 更新情報をチェックする
Red Wine Audio Isabellina HPA LFP-V Edition Pro DAC (バランス伝送対応) バッテリー駆動型DAC搭載真空管ヘッドホンアンプ ハイレゾ音源対応 RED-1344

Rolex day-date 40自動シャンパンダイヤル18 kt黄色ゴールドメンズ時計228238 CRSP

田中貴金属ゴールドバー 100g 田中貴金属発行 100gの純金 24金 ゴールド インゴット

純金製 阿弥陀如来像(御西)(大)

宗派別正式腕輪 曹洞宗 伽羅 共仕立て

宗派別正式腕輪 浄土宗 伽羅 共仕立て