1. Введение
国際サミットで外交官になったつもりで想像してみて:みんなそれぞれの言語と文字を使って話してる。お互い理解するには共通の翻訳ルールが必要だよね。コンピュータの世界では、それがエンコーディングの役割なんだ。
コンピュータが理解するのはたった一つの「言語」だけ――0と1の列。0 と 1 がその「アルファベット」。情報は全部バイトで保存・伝送される。1バイトは 8 ビット(例えば 01000001)だよ。
じゃあ、どうやって僕たちの文字や記号をバイトと結びつけるの?どうやってコンピュータは文字「А」がただの0/1の列じゃなくて画面上のあの文字だって分かるの?
Кодировка
エンコーディングは、文字(文字、数字、記号、漢字、絵文字など)がどのようにバイト列に変換され、そのバイト列がどうやって元の文字に解釈されるかを定めるルールのセット(対応表)だよ。
アナロジーで言えばモールス信号:テキストを点と線に変換して送って、受け取り側が同じルールで文字を復元する。コンピュータでは「バイト ↔ 文字」の取り決めがエンコーディングってわけ。
2. Зачем же нам нужна эта головная боль с кодировками?
- 人間とマシンの間の翻訳:エンコーディングがないとテキストはただのバイト列;エンコーディングがあると意味のある文字になる。
- 互換性と共通性:異なるプログラムやOSがルールを共有する必要がある。ファイルが UTF-8 と宣言されているなら、読む側も UTF-8 で読むべき。
- 多言語・多記号のサポート:キリル文字、アラビア文字、漢字、数学記号、絵文字――扱う文字が多いほどエンコーディングは複雑で柔軟である必要がある。
3. ASCII – «первобытная» кодировка
最も古く基本的なエンコーディングの一つが ASCII(American Standard Code for Information Interchange)だ。これは文字あたり 7 ビットを使うので、128 種類の文字を表現できる:ラテン文字(A-Z, a-z)、数字(0-9)、句読点、制御コード(改行、タブなど)だね。
| 文字 | 10進コード (ASCII) | 2進コード(7ビット) |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| スペース | |
|
歴史的に8ビット目はパリティビットに使われていたことが多く、その後「拡張」された ASCII が出てきた――ロケールごとの単一バイトセットが生まれて、混乱のもとになったんだ。
例えば「Hello」と書くと、ディスク上ではだいたいこんな感じになる(1文字につき1バイト;7ビットASCIIでは上位ビットは0):
H (01001000) e (01100101) l (01101100) l (01101100) o (01101111)
単純だね。でもロシア文字や漢字はどこにある?ASCII には存在しない――基本ラテン文字向けの「単言語辞書」なんだ。
4. «Кракозябры» — почему кодировка это не шутки
時々ファイルを開くと Привет のように見えて、本当は「Привет」だった、なんてことがあるよね。ロシア語の「кракозябры」は日本語だと「文字化け」って呼ばれる(または Mojibake)――これはバイトを間違ったエンコーディングで読んでしまった結果なんだ。
例えば「Привет, мир!」を Windows-1251 で保存したとする。ロシア文字「Привет」のバイトは簡略化するとこうなるかも:
- П → 207
- р → 240
- и → 232
- в → 226
- е → 229
- т → 242
で、同僚がそのファイルを ISO-8859-1(Latin-1)を期待するエディタで開いたり、あるいはあなたがコーディングで StreamReader を明示的なエンコーディング指定なしで使ったりすると、ファイルのエンコーディングと合わなくなる。結果としてバイト 207 は別のテーブルの文字として解釈され、テキストが壊れるんだ。
| オリジナル文字 (Windows-1251) | バイト表現(例) | ISO-8859-1 として読んだ場合の文字 |
|---|---|---|
| П | |
Ç |
| р | |
à |
| и | |
è |
| в | |
â |
| е | |
å |
| т | |
ò |
結果的に Çàèâåò のようになって、「Привет」ではなくなる。期待するエンコーディングにその文字自体が存在しない場合は、□や?みたいな記号が表示されることもある。
ここからの実用的な教訓:テキストを読み書きするときはエンコーディングを明示しておくことが大事。特にデータの出どころが自分の管理外ならなおさら。.NET では StreamReader/StreamWriter に適切な Encoding(例えば UTF-8 や Encoding.GetEncoding("windows-1251"))を渡すことで、この「文字化け」を避け、システム間で正しくデータをやり取りできるようにするんだ。
次のレクチャーでは、ファイルやストリームを扱うときにどのようにエンコーディングを確実に選んで指定するかを学んでいくよ。君のコードがよりユニバーサルで国際化対応、そして堅牢になるようにするためね。
GO TO FULL VERSION