いがにんのぼやき

WEBエンジニアのブログ。IT、WEB、バンド、アニメ。

バイナリから文字エンコードを確認する

あるサーバーで問題があり、配信されているHTMLファイルが文字化けしていて謎の文字エンコードになっていたことがあり、各エディタでも正しく文字エンコードが認識できなかったのでバイナリから文字エンコードを特定できるのか調べて試してみた
(結局そのファイルは本当におかしくなっていたようで文字エンコードが特定出来はしなかったが)
試した環境はWSL上のUbuntu

以下のようなHTMLファイルがUTF-8で保存されているとき

<div>テストtest</div>

hexdump -C でバイナリを確認することが出来る

$ hexdump -C test-utf8.html
00000000  3c 64 69 76 3e e3 83 86  e3 82 b9 e3 83 88 74 65  |<div>.........te|
00000010  73 74 3c 2f 64 69 76 3e  0a                       |st</div>.|
00000019

大体文字エンコードUTF-8、Shift-JIS、EUC-JP、UTF-16あたりのどれかで間違って保存されていることが多いと思うのでそれぞれのマルチバイトの文字列がそれぞれバイナリだとどのような値になるか確認する

例えば上のHTMLには「テスト」というマルチバイト文字列が含まれているので「テスト」という文字列のそれぞれの文字エンコードでのバイナリを確認してみる
echo で文字列出力→ iconv -t [エンコード形式] で指定の文字エンコードに→ hexdump -C でバイナリ出力、という流れ
iconvを挟んだ時に改行が挟まるので最後に 0a がついていることに注意

$ echo "テスト" | iconv -t UTF-8 | hexdump -C
00000000  e3 83 86 e3 82 b9 e3 83  88 0a                    |..........|
0000000a

$ echo "テスト" | iconv -t Shift-JIS | hexdump -C
00000000  83 65 83 58 83 67 0a                              |.e.X.g.|
00000007

$ echo "テスト" | iconv -t EUC-JP | hexdump -C
00000000  a5 c6 a5 b9 a5 c8 0a                              |.......|
00000007

$ echo "テスト" | iconv -t UTF-16 | hexdump -C
00000000  ff fe c6 30 b9 30 c8 30  0a 00                    |...0.0.0..|
0000000a

上のHTMLを見てみるとUTF-8e3 83 86 e3 82 b9 e3 83 88 が含まれていることが分かるのでこれはUTF-8で保存されたファイルだということが特定できる