ざっくり文字化け解説
この文書は、少なくない頻度で文字化けについて解説する機会があるため、次回以降「これを見てね。」と済ませるために書いたものである。
細かいことを抜きにしたら、必要な知識はこれだけだ。
よく知られているように、コンピュータの世界は大量のビット——0または1のいずれかの状態をとるもの——によって構築されている。画面上で見ている文字列も勿論例外ではなく、文字列はビット列に対応付けが行われて表示されている。文字列とビット列の対応を文字コードといい、対応付けることを符号化という。
我々の生活圏でよく目にする文字コードには次のようなものがある。
- UTF-8
- EUC JP
- Shift JIS
それぞれの文字コードは、文字列「あいうえお」をどのように符号化するのだろうか。Pythonでは次のようにして簡単に確認することができる。
$ python
>>> print("あいうえお".encode('shift-jis'))
b'\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8'
>>> print("あいうえお".encode('utf-8'))
b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a'
>>> print("あいうえお".encode('euc-jp'))
b'\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa'
ここで、\x82
というのは16進数で82という意味。したがって、10進数で130、2進数で10000010という意味だ。
あなたが、「あいうえお」を「Shift JIS」で\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8
と符号化したとしよう。
誰かが、\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8
を「Shift JIS」ではない別の文字コードで解釈しようとするとどうなるだろうか。
これが文字化けだ。
したがって、文字化けに遭遇した時にあなたにできることは「ビット列を符号化した文字コードでビット列を解釈する」ということになる。
Note
前述したように、我々の生活圏で使用される文字コードは限られているので、慣れてくると文字化けした文字列を見て「その文字列を符号化した文字コードと、ビット列を解釈する際に使用した文字コード」を推測できる場合もある。
解釈しようとしているビット列が無意味な値の場合もある。例えば、文字化けした文字列を符号化した場合とか。この場合にできることは何もない。
あなたが開発者の場合には、どの時点で文字化けが起きているのか問題の切り分けを行う必要がある。ソースコードをコンパイルしたときなのか、データベースに登録したときなのか、データベースから取得したときなのか、クライアントが解釈するときなのか等々。