1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

文字化けはなぜ起こる?

Posted at

きっかけ

とある実装を任され、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)
     ↓
無効なバイト列として解釈
     ↓
表示: 「�」や「?」(文字化け)

まとめ

文字コードの歴史は長く、さまざまな背景や、規格の乱立などの変遷があって成り立っていることを、調べていく中で知れました。

スタンダードな技術を学んだとしても実務で即役立つわけではないですが、変わらない普遍的な技術を学び、根幹を知ることはエンジニアとして大切なことだと思っているので、今後も引き続き学んでいければと思いました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?