最終更新:

Unicode とは?文字コードの基本をわかりやすく解説

約 8 分で読めます

「文字化け」に悩まされた経験はありませんか。その原因の多くは文字数とバイト数の違い。この記事では、現代のテキスト処理に欠かせない Unicode の基本を解説します。

意外と知らない Unicode のトリビア

Unicode には 2025 年 9 月公開のバージョン 17.0 時点で 159,801 文字が収録されていますが、その中には「実用的とは言いがたい」文字も含まれています。たとえば、Unicode 6.0 で追加された絵文字「💩」(U+1F4A9、Pile of Poo) は、日本の携帯電話向け絵文字を起源とする文字です。国内キャリアが独自に実装していた絵文字セットを Unicode へ取り込む際、既存の端末やメールとの互換性を保つ必要があったため、この種の文字もまとめて収録されました。また、Unicode には「幽霊文字」と呼ばれる謎の漢字が存在します。JIS X 0208 規格の策定時に、出典不明のまま収録されてしまった漢字が約 12 文字あるとされ、「妛」「彁」「挧」などがその例です。これらは実際の日本語文献での使用例がほとんど確認されておらず、規格策定時の転記ミスや誤読が原因ではないかと推測されています。

文字コードとは

コンピュータは文字を数値として扱います。どの数値がどの文字に対応するかを定めたルールが「文字コード」です。代表的な文字コードには以下があります。

文字コード特徴主な用途
ASCII英数字・記号のみ (128 文字)英語圏の基本
Shift_JIS日本語対応 (約 7,000 文字)Windows 日本語環境
EUC-JP日本語対応Unix/Linux 日本語環境
Unicode (UTF-8)世界中の文字に対応 (約 16 万文字)Web 標準

ここで注意すべきは、「文字コード」と「エンコーディング」は厳密には異なる概念だという点です。Unicode は文字の集合とコードポイントの割り当て (文字集合) を定義する規格であり、UTF-8UTF-16 はその Unicode のコードポイントをバイト列に変換する方式 (エンコーディング) です。Shift_JIS は文字集合とエンコーディングが一体化した規格であるのに対し、Unicode は文字集合とエンコーディングを分離した設計になっています。この分離により、同じ Unicode 文字集合に対して用途に応じた複数のエンコーディングを選択できるようになりました。

Unicode が生まれた背景

Unicode の構想が始まったのは 1987 年頃とされています。当時、Xerox 社の Joe Becker 氏と Apple 社の Lee Collins 氏、Mark Davis 氏らが中心となり、「世界中の文字を 16 ビット (65,536 文字) で表現する」という野心的な計画を立てました。当初は 65,536 文字で十分と考えられていましたが、中国・日本・韓国の漢字 (CJK 統合漢字) だけでも数万文字に上ることが判明し、最終的に 21 ビット (約 110 万文字分) の空間に拡張されました。この「最初の見積もりの甘さ」が、後の UTF-16 におけるサロゲートペアという複雑な仕組みを生む原因になったとされています。

Unicode のバージョン履歴を見ると、収録文字数の成長は段階的です。1991 年の Unicode 1.0 では約 7,000 文字でしたが、1999 年の Unicode 3.0 で約 49,000 文字に拡大し、CJK 統合漢字拡張 A が追加されました。2010 年の Unicode 6.0 で携帯電話由来の絵文字が大規模に収録されて約 110,000 文字に到達し、2025 年 9 月公開の Unicode 17.0 では 159,801 文字を収録しています。特に CJK 統合漢字は全体の約 6 割を占めており、Unicode の文字空間がいかに東アジアの文字体系に依存しているかがわかります。

CJK 統合漢字には「Han Unification (漢字統合)」と呼ばれる設計判断が含まれています。中国語・日本語・韓国語で字形が微妙に異なる漢字を、同一のコードポイントに統合したのです。たとえば「直」という字は、日本語と中国語 (簡体字) で微妙に画数や形が異なりますが、Unicode では同じ U+76F4 に割り当てられています。この統合は、コードポイントの節約という実用的な理由から行われましたが、日本語フォントで表示すべき文字が中国語フォントで表示されるといった問題を引き起こすことがあり、CJK 圏の開発者の間では今も議論が続いています。

UTF-8 と UTF-16 の違い

Unicode にはいくつかのエンコーディング方式があります。

方式1 文字あたりのバイト数特徴
UTF-81〜4 バイトASCII 互換、Web 標準
UTF-162 または 4 バイトJavaScript 内部で使用
UTF-32固定 4 バイト処理が単純だがサイズ大

Web では UTF-8 が事実上の標準です。HTML ファイルの先頭に <meta charset="UTF-8"> と記述するのはこのためです。

UTF-8 が可変長エンコーディングである理由は、そのビットパターンの設計にあります。先頭バイトのビットパターンで文字のバイト数が決まる仕組みです。0xxxxxxx なら 1 バイト (ASCII 互換)、110xxxxx なら 2 バイト、1110xxxx なら 3 バイト、11110xxx なら 4 バイトです。後続バイトは常に 10xxxxxx の形式をとります。この設計により、バイト列の途中からでも文字の境界を特定でき、ストリーム処理やランダムアクセスに強いという利点があります。一方、UTF-16 は BMP 内の文字を 2 バイトで表現し、BMP 外の文字 (U+10000 以上) にはサロゲートペアという仕組みを使います。上位サロゲート (U+D800〜U+DBFF) と下位サロゲート (U+DC00〜U+DFFF) の 2 つの 16 ビット値を組み合わせて 1 文字を表現するため、絵文字や一部の漢字を扱う際に注意が必要です。

なぜ UTF-8 が Web の標準になったのでしょうか。UTF-8 は 1992 年に Ken Thompson 氏と Rob Pike 氏 (後に Go 言語を設計した人物) がレストランのナプキンに設計図を描いたことから生まれたとされています。UTF-8 の最大の利点は ASCII との完全な後方互換性です。既存の ASCII テキストはそのまま有効な UTF-8 テキストとして扱えるため、移行コストが極めて低く、Web の普及とともに急速に広まりました。W3Techs の利用状況調査では、文字エンコーディングが判明している Web サイトのうち 99.0% が UTF-8 を使用しています (2026 年 8 月時点)。

文字コードを間違えるとこうなる ― 文字化けの実例

文字コードの不一致は、さまざまなトラブルを引き起こします。

文字数カウントへの影響

同じ文字列でも、エンコーディングによってバイト数は異なります。たとえば「こんにちは」は 5 文字ですが、UTF-8 では 15 バイト、Shift_JIS では 10 バイトになります。文字数カウントスでは文字数とバイト数の両方を表示するため、用途に応じた確認が可能です。

さらに注意すべきは、Unicode の「正規化」(Normalization) の問題です。同じ見た目の文字が、内部的に異なるコードポイント列で表現されることがあります。たとえば「が」は、1 つのコードポイント U+304C (NFC 形式) としても、「か」(U+304B) + 濁点 (U+3099) の 2 つのコードポイント (NFD 形式) としても表現できます。macOS の旧ファイルシステム HFS+ は、ファイル名を NFD に近い分解形へ正規化して保存する仕様でした。後継の APFS は入力された形をそのまま保持しますが、HFS+ 時代に作られた名前や macOS 経由で受け渡したファイル名には分解形が混ざりやすく、NFC を前提とする Windows や Linux 側で名前を照合するとファイルが見つからない、ZIP を展開したら濁点が分離して見える、といった問題が起こります。プログラムで文字列比較を行う際は、事前に NFC に正規化しておくことが推奨されます。

絵文字と Unicode ― 見た目 1 文字が 1 文字とは限らない

絵文字は Unicode の中でも特に複雑な領域です。絵文字の文字数カウントの仕組みで詳しく解説していますが、見た目は 1 文字でも、内部的には複数のコードポイントで構成されることがあります。たとえば「👨‍👩‍👧‍👦」(家族の絵文字) は 7 つのコードポイントから成り、プログラムによっては 7 文字とカウントされる場合があります。

この仕組みは ZWJ (Zero Width Joiner、ゼロ幅接合子、U+200D) と呼ばれる特殊文字によって実現されています。「👨‍👩‍👧‍👦」は実際には「👨 + ZWJ + 👩 + ZWJ + 👧 + ZWJ + 👦」という 7 つのコードポイントの連結です。肌の色のバリエーション (👋🏻👋🏽👋🏿) も、基本の絵文字 + 肌色修飾子 (Skin Tone Modifier) の 2 つのコードポイントで構成されています。このため、JavaScript の "👨‍👩‍👧‍👦".length は 11 を返します (UTF-16 のサロゲートペアも含むため)。正確な「見た目の文字数」を取得するには、Intl.Segmenter API や Unicode のグラフェムクラスタ分割を使用する必要があります。

プロが実践する文字コード管理テクニック

文字コードに関するトラブルを未然に防ぐために、プロのエンジニアやライターが実践しているテクニックを紹介します。

  1. プロジェクトの .editorconfig でエンコーディングを統一する。charset = utf-8 を設定しておけば、チームメンバー全員が同じエンコーディングでファイルを作成できます。
  2. Git の .gitattributes で改行コードとエンコーディングを管理する。* text=auto を設定すると、OS 間の改行コードの違いを自動的に処理してくれます。
  3. テキストエディタのステータスバーでエンコーディングを常に確認する。VS Code では右下にエンコーディングが表示されており、クリックすることで変換も可能です。
  4. API やデータベースでは utf8mb4 を標準にする。「とりあえず UTF-8」ではなく、絵文字にも対応した utf8mb4 を最初から選択しておくことで、後からの移行コストを回避できます。

Unicode の「未来」― まだ埋まっていない空間

Unicode は最大で 1,114,112 個のコードポイント (U+0000〜U+10FFFF) を収容できる設計ですが、2025 年 9 月公開の Unicode 17.0 で割り当て済みの文字は 159,801 文字です。つまり、全体の約 14% しか使われていません。残りの空間には、今後整理される歴史的な文字体系や新しい絵文字のための領域、アプリケーションが自由に使える私用領域、そして将来の用途に備えた予約領域が含まれています。Unicode Consortium は近年おおむね年 1 回のペースで新しいバージョンを公開しており、絵文字も版ごとに追加が続いています。

よくある誤解と注意点

Unicode に関しては、経験豊富な開発者でも誤解しがちなポイントがいくつかあります。

まとめ

Unicode は現代のテキスト処理の基盤であり、その歴史と仕組みを理解することで、文字化けや文字数カウントの問題を根本から解決できます。特に、UTF-8 が Web 標準となった背景や、絵文字の内部構造を知っておくと、システム開発やコンテンツ制作で役立つ場面が多いでしょう。文字数カウントスで文字数・バイト数を確認しながら作業を進めましょう。

この記事を共有