文字エンコーディング: Unicode と UTF-8 の解説
更新 2026-07-06
見たことがあるはずです: José と読めるべき名前が José になったり、絵文字がクエスチョンマークの箱になったり。その化けには名前があります — 文字化け(mojibake) — そしてほぼ必ず文字エンコーディングの不一致です。このガイドは文字・Unicode・UTF-8 が本当に何なのかを説明し、そうしたバグを謎でなくします。
コンピューターは文字ではなく数値を保存する
最も低いレベルではコンピューターは数値(バイト)しか保存しません。テキストを保存するには、各文字を数値に対応させ、また戻す、合意された表が必要です。その表が 文字エンコーディング です。あるプログラムが 1 つの表でテキストを書き、別のプログラムが別の表で読むと、数値が違う文字と解釈され — 文字化けが起きます。
ASCII: 小さな始まり
広く普及した元祖のエンコーディング ASCII は、128 文字 — 英語アルファベット、数字、句読点、いくつかの制御コード — に数値を定めました。英語には十分ですが、é、ü、ß、你、😀 や、世界の言語が使う何万もの文字を入れる余地はありません。何十年も皆がそれぞれ互換性のない拡張を作り、まさにそれがシステム間でテキストが壊れた理由です。
Unicode: すべての文字に 1 つの数値
Unicode は普遍的な解決策です: すべての書記体系のすべての文字、加えて記号や絵文字に、一意の数値 — コードポイント(code point) — を割り当てる単一の標準です。コードポイントは U+ の後に 16 進数を付けて書きます:
A → U+0041 é → U+00E9 你 → U+4F60 😀 → U+1F600
決定的に、Unicode は 数値 を定義しますが、それをバイトとしてどう保存するかは定義しません。それは別の決定で — ここで UTF-8 が登場します。
UTF-8: Unicode がバイトになる仕組み
UTF-8 は Unicode コードポイントをバイトにエンコードする方式で、ウェブが圧倒的に使うものです。その巧妙な設計は 可変長 であることです:
- 128 個の ASCII 文字はそれぞれ 1 バイト — なので UTF-8 は ASCII と後方互換です。
- アクセント付きラテン文字やギリシャ・キリル文字のほとんどは 2 バイト。
- 中国語・日本語・韓国語を含むほとんどの他の文字は 3 バイト。
- 絵文字やより稀な文字は 4 バイト。
だから「100 文字」の文字列が常に 100 バイトとは限りません: 1 文字が数バイトになり得ます。古典的な José バグもこれで説明できます — é の UTF-8 バイトを、古い西欧エンコーディングとして 1 バイトずつ誤って読んだものです。
文字、コードポイント、バイト
関連するが異なる 3 つの概念が人々を絶えず混乱させます:
- 文字(Character) — 人が見るもの(文字
é)。 - コードポイント(Code point) — その Unicode 数値(
U+00E9)。 - バイト(Byte) — 保存のされ方(UTF-8 では 2 バイト
0xC3 0xA9)。
コードポイントがそのまま書き出されたのを見るのが、テキストの問題を診断する最速の方法であることがよくあります — たとえば、実はノーブレークスペース(U+00A0)だった「スペース」。当サイトの Unicode 変換ツール は、どんなテキストの背後にあるコードポイントも表示し、文字とエスケープシーケンスの間を変換します。
文字化けを避ける方法
- どこでも UTF-8 を使う。 ファイルを UTF-8 で保存し、宣言しましょう — ウェブページでは
<meta charset="utf-8">、HTTP ではContent-Typeの charset、データベースでは UTF-8 の照合順序。 - 端から端まで一貫させる。 ほとんどの破損は、一方が別のエンコーディングを想定する境界で起きます。
- 正しい文脈でエスケープする。 特殊文字を HTML に安全に入れるには HTML エンティティ を、URL に入れるには URL エンコード を使いましょう。
手短に言えば: Unicode がすべての文字に数値を与え、UTF-8 がその数値をバイトに変え、皆が UTF-8 を使うことに合意すれば、テキストは壊れなくなります。
データフォーマット & エンコーディング をもっと見る
データフォーマット & エンコーディング のガイドをすべて見る →このガイドで触れたツール