DevToolBox

文字化けの原因特定と直し方 - 「縺」「ã」「□」化け方パターン逆引き

文字化けは化け方を見れば原因がほぼ特定できます。「縺」が並ぶなら UTF-8 を Shift_JIS で誤解釈、「ã」「æ」が並ぶなら Latin-1 で誤解釈、「?」や「�」ならデータは既に 失われています。本記事ではパターン逆引き表と、HTTP ヘッダ・HTML の meta・DB・ファイル保存の 4 か所を順に確認する手順をまとめます。

Garbled Japanese text (mojibake) reveals its own cause: 縺/繧/繝 sequences mean UTF-8 bytes were decoded as Shift_JIS, ã/æ/è sequences mean they were decoded as Latin-1/Windows-1252, while "?" and U+FFFD mean the data was destroyed by a lossy conversion. This guide maps each pattern to its cause, recoverability, and fix.

TL;DR

Unicode Inspector

化けた文字列を貼り付けると、1文字ずつコードポイント(U+XXXX)と文字名を表示。「�」(U+FFFD・復元不能)なのか、フォントが無いだけの正常な文字なのかを即座に判別できます。

今すぐ試す →

1. 化け方パターン逆引き表 / Identify the cause from the pattern

化け方の例 / Pattern原因 / Cause復元 / Recoverable?
縺薙s縺ォ縺。縺ッ(縺・繧・繝が頻出)UTF-8 のバイト列を Shift_JIS(CP932)として解釈可。UTF-8 で読み直す
日本語(ã・æ・è が頻出)UTF-8 を Latin-1 / Windows-1252 として解釈概ね可(例外は §2)
譁・蟄など見慣れない漢字の羅列UTF-8 の漢字(先頭バイト E4〜E9)を Shift_JIS 解釈可。同上
??????Unicode → 旧エンコーディング変換時に表現できず ? へ置換不可。元データを再取得
������(U+FFFD)デコーダが不正なバイト列を置換文字に差し替えた不可
□□□(豆腐)データは正常。フォントにグリフがないだけ壊れていない。フォント変更で表示可

判断に迷ったら、化けた文字列を Unicode Inspector に貼ってコードポイントを確認します。 U+FFFD が見えたら復元不能、U+7E3A(縺)などまともな漢字に化けているなら誤デコードで復元可能、 正しいコードポイントなのに表示できないならフォントの問題です。

The garbled shape tells you the failure mode. Wrong-decode patterns (縺/ã) are reversible; "?" and U+FFFD mean bytes were already destroyed; tofu boxes mean the font lacks a glyph.

2. 「縺」系・「ã」系は復元できる / Reversing wrong-decode mojibake

誤デコードは「化けた文字列を間違えた方のエンコーディングでバイト列に戻し正しい方で読み直す」だけで復元できます。Python は CP932/CP1252 を標準で 扱えるので確認に便利です。

>>> # 「縺」系: UTF-8 を Shift_JIS(CP932) で読んでしまったケース
>>> "縺薙s縺ォ縺。縺ッ".encode("cp932").decode("utf-8")
'こんにちは'

>>> # 「ã」系: UTF-8 を Windows-1252 で読んでしまったケース
>>> "日本語".encode("cp1252").decode("utf-8")
'日本語'

仕組みは単純で、ひらがなの UTF-8 表現は E3 81 xx / E3 82 xx / E3 83 xx の 3 バイトであり、先頭 2 バイトを CP932 の 2 バイト文字として読むとそれぞれ 「縺」「繧」「繝」になるためです。なお CP1252 には 0x81・0x8D など未割り当てのバイトがあり、 そこに当たった文字は上記の方法でも完全には戻らないことがあります。また一度「?」や U+FFFD に 置換された部分は、この方法でも戻りません。

Encode the garbled string back with the wrong codec, then decode as UTF-8. Hiragana's UTF-8 lead bytes E3 81/82/83 map to 縺/繧/繝 in CP932 — that is why those characters dominate.

3. Webなら HTTP ヘッダと meta を確認 / Check HTTP charset and meta

ブラウザ表示が化ける場合、まず疑うのはサーバが返す Content-Type ヘッダです。HTTP ヘッダの charset は HTML の <meta charset> より優先されるため、meta を UTF-8 にしてもヘッダが Shift_JIS なら化けたままです。

$ curl -sI https://example.com/
HTTP/2 200
content-type: text/html; charset=Shift_JIS   ← 本文が UTF-8 ならここが原因

ヘッダに charset がない場合はブラウザが <meta charset="utf-8"> を 参照しますが、HTML 仕様上この宣言はファイル先頭から 1024 バイト以内に 置く必要があります。巨大なコメントや SVG をその前に挟まないこと。サーバ側は nginx ならcharset utf-8;、Apache なら AddDefaultCharset UTF-8、 アプリ側でヘッダを返すなら Content-Type: text/html; charset=UTF-8 に統一します。

The HTTP Content-Type charset overrides the meta tag. Check it with curl -sI first, and keep <meta charset> within the first 1024 bytes of the document.

4. DBの文字コード: MySQL の utf8 と utf8mb4 / Database charset pitfalls

DB 経由の文字化けで最頻出なのが MySQL です。歴史的経緯で utf8 は 3 バイトまでのutf8mb3 の別名であり、4 バイトの絵文字や一部の漢字を保存しようとすると 次のエラーになります。

ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'body' at row 1

対処は utf8mb4 への統一です。さらに厄介なのが接続文字コードの不一致で、 クライアントが latin1 のままだと「化けた状態のバイト列が DB に保存される」二重エンコードが 起き、SELECT しても化けたまま、という最悪パターンになります。現状確認は次の 1 行です。

mysql> SHOW VARIABLES LIKE 'character_set%';
-- character_set_client / _connection / _results がすべて utf8mb4 であること

ALTER TABLE posts CONVERT TO CHARACTER SET utf8mb4;  -- テーブル側
-- 接続側: DSN に charset=utf8mb4 を指定(例: mysql://...?charset=utf8mb4)

MySQL's utf8 is 3-byte utf8mb3; emoji need utf8mb4. Verify client, connection, and results charsets with SHOW VARIABLES LIKE 'character_set%' — a latin1 connection silently stores double-encoded garbage.

5. ファイル保存時の確認手順 / File-save checklist

In VS Code use "Reopen with Encoding" (non-destructive) before "Save with Encoding". Excel needs a UTF-8 BOM for CSV; when in doubt, inspect the raw bytes in hex.

まとめ / Summary

文字化けの調査は「化け方パターンで原因を当てる → 復元可能か判断する → 経路(HTTP・meta・DB・ ファイル)のどこで食い違ったか特定する」の 3 段階で進めます。「縺」「ã」系なら慌てる必要は ありません。データは生きており、正しいエンコーディングで読み直すだけです。「?」「�」に なっていたら元ソースからの再取得が必要です。再発防止は全経路を UTF-8(MySQL は utf8mb4)に統一することに尽きます。

Mojibake debugging is pattern matching. 縺/繧/繝 sequences mean UTF-8 bytes were decoded as Shift_JIS; ã/æ/è sequences mean Latin-1/Windows-1252 — both are fully reversible by re-encoding with the wrong codec and re-decoding as UTF-8. Question marks and U+FFFD replacement characters mean a lossy conversion already destroyed the bytes, and tofu boxes simply mean the font lacks a glyph while the data is intact. Walk the pipeline in order: the HTTP Content-Type charset (which overrides the meta tag), the meta declaration within the first 1024 bytes, the database charset (use utf8mb4 in MySQL, and check the connection charset too), and finally the editor's file encoding. Unify everything on UTF-8 and the problem stays fixed.

Unicode Inspector

BOM(U+FEFF)・ゼロ幅文字・置換文字(U+FFFD)など目に見えない文字もコードポイント単位で可視化。文字化け調査の最初の一手にどうぞ。

今すぐ試す →

関連ツール / Related tools

関連ガイド / Related guides