はじめに
人間とコンピュータでは、文字情報の扱い方に根本的な違いがあります。人間は「あ」「A」「😊」といった文字や絵文字を直接認識できますが、コンピュータはすべてのデータを数値(0と1のビット列)としてしか処理できません。このギャップを埋めるために開発されたのが「文字コード」という仕組みです。
人間の文字認識 と コンピュータのデータ表現
人間の文字処理の特徴
・視覚的な形で文字を認識
・文脈に応じて同じ形の文字でも意味を柔軟に解釈
・数千~数万種類の文字を区別して理解可能
コンピュータのデータ処理の特徴
・すべてのデータは0と1のビット列(2進数)で表現
・事前に定義された規則に対し厳密に従う必要がある
・メモリ効率を重視するため、できるだけ少ないビット数で表現しようとする
基本的な仕組み
文字コードは、コンピュータ上で文字を扱うために、文字に対して割り当てられた数値のことで、人間とコンピュータのデータ橋渡しを行なう技術のことです。
「文字 ⇔ 数値」の対応表(マッピング)として機能しています。
人間が読める文字をコンピュータが扱える数値に翻訳することをエンコード、その逆をデコードといいます。つまり、双方が理解できる形式に文字や数字を翻訳する際の対応表になっているのが文字コードです。
エンコード
人間が理解する文字 → 文字コードによるエンコード → コンピュータが扱える数値
※エンコードのことを「符号化」
デコード
コンピュータの数値 → 文字コードによるデコード → 人間が理解する文字
文字コードの主要構成要素
前提:文字からバイト列への変換プロセス
文字からバイト列への変換は、必ずコードポイントを介した2段階のプロセスで行われます。
文字 → コードポイント → バイト列
※基本的に、直接文字がバイト列になるわけではない。ただし、Shift-JISは直接変換される。
符号化文字集合
世界中の文字に「U+XXXX」形式のID(コードポイント)を割り当てられています。
これはいわば辞書のようなもので、例えば、Unicodeで「A」は「U+0041」、「あ」は「U+3042」とあらかじめ定義されています。
しかし、これはあくまでも文字とコードポイントを対応づけただけです。そこで、コードポイントをバイト列に変えるため、エンコーディングが必要になります。
これにより、同じコードポイントを使用しても、エンコーディング方式を変えるだけでバイト表現を変えることができます。
エンコーディング方式
コードポイントを実際のバイト列に変換する方法のことです。
(例)UTF-8、UTF-16、Shift_JISなど
主要な文字コードの種類と特徴
1. ASCII(アスキー)コード
・7ビット(128文字)の文字コード
・英数字、記号、制御文字のみ
・1文字=1バイト(実際は7ビットだが、8ビット単位で扱われる)
(例)'A' → 65 (0x41)、'0' → 48 (0x30)
2. 拡張ASCII(ISO-8859シリーズ)
ASCIIを8ビット(256文字)に拡張
・地域ごとに異なるバリエーション(ISO-8859-1:西欧、ISO-8859-7:ギリシャなど)
・日本語は表現できない
3. Shift_JIS(シフトJIS)
日本語を扱えるようにした文字コード
・ASCII互換性を維持しつつ、日本語文字を表現
・2バイト文字と1バイト文字が混在
・問題点:文字化けが発生しやすい
4. Unicode(ユニコード)
世界中の文字を単一の文字集合で扱うことを目的に開発
・最新版(2023年時点)で149,813文字を定義
主要なエンコーディング方式
・UTF-8:可変長(1~4バイト)、ASCII互換、Webで主流
・UTF-16:2バイトまたは4バイト固定、JavaやWindowsで使用
・UTF-32:4バイト固定、処理が単純だがメモリ効率が悪い
文字化けのメカニズムと防止策
文字化けが起こる理由
・エンコーディング方式の不一致(例:UTF-8でエンコードしたデータをShift_JISとして解釈)
・サポート外の文字を使用
・データ転送中のエラー
文字化け対策
・システム全体でUTF-8を使用する
・ファイルの先頭にBOM(Byte Order Mark)を付加(ただし、UTF-8では不要な場合も)
・メタデータ(HTMLのcharset、HTTPヘッダーなど)でエンコーディングを明示
・特殊文字を使用する際は文字参照(例:あで「あ」)を利用
まとめ
はじめのうちは、UnicodeやASCIIコードなど、言葉と定義・意味がごちゃごちゃしてしまうと思いますが、人間とコンピュータが文字をどのように表現するかを理解することで、なぜ文字化け対策などで文字コードが重要なのかが理解できると思います。
筆者もはじめ、この違いがいまいちよく理解できておらず、なぜHTMLのmeta要素でcharsetを行なうのか理解できていませんでした。
この点がクリアになると、コードの意味が理解できるようになります。
最後までお読みいただき、ありがとうございました。
参考URL
http://equj65.net/tech/charcode/
https://gigazine.net/news/20231005-unicode/
https://qiita.com/omiita/items/50814037af2fd8b2b21e
https://qiita.com/yuji38kwmt/items/b3a7820b4d3b544da4ff
https://www.gixo.jp/blog/12465/
https://itskillmap.com/menu2_02/