文字コードを推定する: 文字化け直しツールが Shift_JIS を見分ける方法

ファイルには、自分の文字コードが書かれていない。バイトの並びと「日本語らしさ」から当てる方法と、戻せる文字化け・戻せない文字化け。

公開: 2026年9月17日 / 更新: 2026年9月17日 / 文: おたすけ

「譁�ュ怜喧縺代r逶エ縺�」。これは「文字化けを直す」という文字列を UTF-8 で保存し、Shift_JIS のつもりで読み込んだ結果である。取引先から届いた CSV を Excel で開いたら、こういう文字が並んでいた、という経験のある人は多いだろう。ファイルが壊れたわけではない。中身のバイト列は正しいまま、読む側が文字コードを取り違えただけだ。

文字化け直しツール は、ファイルの文字コードを推定し、Excel で開ける形式に変換し直す。推定と書いたのは、ファイルのどこにも「私は Shift_JIS です」とは書かれていないからである。書かれていないものを、どうやって当てるのか。

文字コードはファイルに書かれていない

コンピュータのファイルは、0 から 255 までの数(バイト)の並びでしかない。文字コードは、その並びを文字に対応づける約束事である。同じ「文字化けを直す」でも、Shift_JIS で保存すると 14 バイト、UTF-8 で保存すると 21 バイトになり、並びはまったく違う。

Shift_JIS  95 B6 8E 9A 89 BB 82 AF 82 F0 92 BC 82 B7
UTF-8      E6 96 87 E5 AD 97 E5 8C 96 E3 81 91 E3 82 92 E7 9B B4 E3 81 99

冒頭の文字化けは、下の UTF-8 のバイト列を、Shift_JIS の約束事で読んだ結果である。

ふつうのテキストファイルは、自分がどの約束事で書かれたかを記録していない。例外は BOM(バイトオーダーマーク)と呼ばれる目印で、ファイルの先頭が EF BB BF なら UTF-8、FF FE なら UTF-16 だとわかる。ただし BOM は付けても付けなくてもよく、Shift_JIS にはそもそも BOM がない。多くのファイルでは、中身を見て当てるしかない。

読めるかどうかで、まず候補を絞る

ツールは、確実な手がかりから順に調べていく。

最初に BOM を見る。あれば、その文字コードで確定である。次に、ISO-2022-JP(古いメールで使われてきた形式)に特有の ESC $ B のような切り替えの記号を探す。この形式は 0〜127 のバイトしか使わず、UTF-8 として読んでも規則違反にならないので、先に見分けておく必要がある。0〜127 のバイトしか含まないファイルは英数字だけの文書で、どの文字コードで読んでも結果は同じなので、UTF-8 として扱う。

手がかりとして次に強いのが、UTF-8 の規則である。UTF-8 には、バイトの並び方に厳しい規則がある。先頭が E6 のような値なら、そのあとに 80BF のバイトがちょうど 2 個続かなければならない。Shift_JIS のファイルをこの規則で読むと、日本語が数文字あるだけで、ほぼ確実にどこかで違反する。ブラウザが標準で持つ TextDecoder には、違反を見つけたらエラーにする設定がある(Encoding Standard)。最後までエラーなく読めたら、UTF-8 と判定する。

UTF-8 でなかった場合は、encoding-japanese というライブラリに候補を一つ挙げてもらう。このライブラリはバイトの出現の仕方から Shift_JIS、EUC-JP などを見分けるが、どれくらい自信があるかは返さない。開発前に、同じ用途の jschardet と chardet も試した。1〜3 行しかない短い Shift_JIS の文書を読ませると、この二つは別の文字コードと答え、正しく当てたのは encoding-japanese だけだった。

読んだ結果が日本語らしいか

ライブラリの答えを、そのまま信じるわけにはいかない。そこで、候補の文字コードすべてで実際に読んでみて、読めた文字列がどれくらい日本語らしいかを点数にする。

先ほどの Shift_JIS のバイト列を、四つの文字コードで読むとこうなる。

Shift_JIS  文字化けを直す
UTF-8      ���������𒼂�
EUC-JP     �������
UTF-16LE   뚕骎뮉꾂벒랂

は、約束事に合わないバイトを読んだときに出る置き換え文字である。UTF-16LE で読むと置き換え文字は出ないが、韓国語のハングルや見慣れない漢字が並ぶ。バイト列は何かしらの文字にはなるので、読めたかどうかだけでは正解を選べない。

点数は、英数字以外の文字を一つずつ見て付ける。ひらがな、カタカナ、漢字、全角の英数字や記号は加点し、半角カナは少しだけ加点する。置き換え文字は大きく減点し、それ以外の文字(ハングルや特殊な記号など)も減点する。合計を文字数で割り、0 から 1 に収める。上の例では、Shift_JIS で読んだものが 1、ほかの三つは 0 になる。

ライブラリが挙げた候補の点数が 0.3 以上ならそれを採る。0.3 に届かず、ほかに 0.3 以上の候補があれば、いちばん点数の高いものに乗り換える。画面に出す「確からしさ」も点数で決めていて、置き換え文字が一つでも混じれば「低」、0.6 以上で「高」、0.3 以上で「中」とする。

それでも外れることはある。そもそも判定に使うのはファイルの先頭 1 MB だけで、その範囲に日本語がほとんどなければ手がかりが足りない。そのためツールは、判定結果と一緒に変換後の先頭 30 行を表で見せ、文字コードを手で選び直せるようにしている。判定は当て推量で、最後に確かめるのは画面を見る人の目である。

読むのは簡単で、書くほうに手間がかかる

判定が済めば、あとは読み替えて書き出すだけである。読み込み側は、ブラウザの TextDecoder が Shift_JIS、EUC-JP、ISO-2022-JP、UTF-16 にまで対応しているので、ライブラリは要らない。

ところが、書き出し側は事情が違う。文字列をバイト列にするブラウザ標準の TextEncoder は、UTF-8 にしか変換できない(Encoding Standard)。Shift_JIS で書き出すには、ここでも encoding-japanese を使う。

Shift_JIS に変換すると、失われる文字が出る。絵文字や「𠮷」のように Shift_JIS に存在しない文字は ? になる。「〜」(波ダッシュ)が「~」に、「−」が「-」に変わるように、見た目の近い別の文字に置き換わるものもある。ツールは変換した文字を一つずつ元に戻して比べ、変わった文字と失われた文字の数を表示する。

出力の既定は、Shift_JIS ではなく BOM 付きの UTF-8 にしている。日本語版の Excel は、BOM のない CSV を Shift_JIS として読むので、UTF-8 の CSV は冒頭の例のように化ける。先頭に EF BB BF の 3 バイトを付けておくと、Excel は UTF-8 として開く。この方法なら、Shift_JIS に変換したときのように文字が失われることもない。

大きなファイルは、画面の操作が止まらないよう、Web Worker(画面の処理とは別に動かせる処理の単位)の中で、少しずつ読んでは書き出す。

貼り付けた文字化けを戻せる場合、戻せない場合

ファイルではなく、化けた文字列そのものを貼り付けて直す機能もある。ただし、冒頭の「譁�ュ怜喧縺代r逶エ縺�」を貼り付けても、候補は一つも出てこない。

直す手順は、読み違いを逆にたどることである。「UTF-8 のバイト列を Shift_JIS で読んだ」と仮定し、化けた文字列を Shift_JIS のバイト列に戻してから、UTF-8 として読み直す。この逆算が成り立つのは、読み違えたときにバイトの情報が一つも失われていない場合に限られる。冒頭の例には置き換え文字 が混じっている。Shift_JIS の約束事に合わないバイトが、その時点で捨てられたということで、捨てられたバイトは逆算しても戻らない。

ツールは、UTF-8 を Shift_JIS で読んだ場合、UTF-8 を Latin-1(欧文の文字コード)で読んだ場合、EUC-JP と Shift_JIS を取り違えた場合など、五通りの読み違いを順に仮定して逆算する。結果に置き換え文字が出たものは捨て、元の文字列より日本語らしくなったものだけを候補として並べる。「縺薙s縺ォ縺。縺ッ」は「こんにちは」に戻る。「????」のように、すでに ? に置き換わった文字列は、どの仮定でも戻らない。そういうときは、元のファイルをそのまま渡してもらうのがいちばん確実である。

判定も変換も逆算も、ブラウザの中で行う。このツールのサーバーは静的なファイルを配るだけで、ファイルの中身も名前も受け取らない。取引先の CSV のように、他人のデータが入ったファイルを扱う道具としては、そうである必要があった。