きっかけ
とある実装を任され、RFCを読み漁る中で、文字コードに対する関心が深まりました。日常的な業務ではそれほど深く理解していなくても、なんとかなってしまう場面が多いですが、学べる時に学んでおいて損はないなと思ったのがきっかけです。
文字コードとは?のような用語の説明はしません。文字コードの変換プロセスに焦点を当てて説明しています。
文字コードはシンプル
コンピュータは人間の文字をそのまま理解することはできないので、内部で文字を数字に変換しています。例えば「あ」を入力するとコンピュータでは以下のような2進数に変換されます。
あ -> 11100011 10000001 10000010
コンピュータは0か1しかわからないので、2進数に変換する必要がありますが、それだと人間にとって冗長でわかりにくく、効率的ではないので、16進数として表現します。
あ -> 11100011 10000001 10000010 → E3 81 82
この「文字」と「バイト列」の対応関係を「文字コード」と呼びます。
変換の流れ
まず、「あ」を入力すると、Unicode のコードポイントに変換されます。
入力:「あ」
↓
コードポイント: U+3042(Unicode)
次にコードポイントを2進数に変換します。ユニコードのコードポイント U+3042 は16進数で表現されますが、コンピュータでは2進数として扱われます。U+3042 を2進数に変換すると以下のようになります。
コードポイント: U+3042
↓
2進数: 0011 0000 0100 0010
次にこの2進数データを UTF-8 などのエンコード方式に基づいてバイト列に変換します。UTF-8 ではコードポイントが次のようにエンコードされます。
2進数: 0011 0000 0100 0010
↓
UTF-8バイト列:
- 1バイト目: 11100011 (E3)
- 2バイト目: 10000001 (81)
- 3バイト目: 10000010 (82)
↓
バイト列: E3 81 82
文字化けが発生する流れ
正常な場合
バイト列: E3 81 82
↓
UTF-8デコード:
- 1バイト目: 11100011 (E3)
- 2バイト目: 10000001 (81)
- 3バイト目: 10000010 (82)
↓
2進数: 0011 0000 0100 0010
↓
コードポイント: U+3042
↓
表示: 「あ」
文字化けが発生する場合
バイト列: E3 81 82 (UTF-8)
↓
デコード (Shift-JIS)
↓
無効なバイト列として解釈
↓
表示: 「�」や「?」(文字化け)
まとめ
文字コードの歴史は長く、さまざまな背景や、規格の乱立などの変遷があって成り立っていることを、調べていく中で知れました。
スタンダードな技術を学んだとしても実務で即役立つわけではないですが、変わらない普遍的な技術を学び、根幹を知ることはエンジニアとして大切なことだと思っているので、今後も引き続き学んでいければと思いました。