情報ラボ > 文字コード
「あ」も「A」も、コンピュータの中では番号です。どんな番号なのか、確かめてみましょう。
枠の色は、その文字がUTF-8で何バイト必要かを表しています。
マスをクリックすると、その文字の番号が下に表示されます。縦が上位、横が下位の16進数です。
数字の 0〜9 は 48〜57、大文字 A〜Z は 65〜90、小文字 a〜z は 97〜122 と、連続して並んでいます。 大文字と小文字は32だけ離れているので、2進数で見ると6桁目が違うだけです。 この規則のおかげで、文字の並べ替えや大文字小文字の変換が簡単な計算でできます。
同じ数値の並びを、違うルールで読み取るとどうなるかを再現します。
UTF-8で書いて、UTF-8で読む
UTF-8で書いたものを、1バイトずつの文字として読む
データそのものは同じです。違うのは「どう区切って、どう読むか」というルールだけです。
コンピュータが扱えるのは0と1だけです。では、文字はどうやって扱っているのでしょうか。答えは単純で、文字の一つ一つに番号をふっているのです。
「A」は65番、「B」は66番、というように、あらかじめ対応表を決めておきます。この対応表を文字コードといいます。コンピュータは65という数値を受け取ると、対応表を見て「A」という形を画面に描きます。
大切なのは、書き手と読み手が同じ対応表を使っている必要があるという点です。違う表を使うと、まったく別の文字として解釈されてしまいます。
1963年にアメリカで定められたのがASCII(アスキー)です。アルファベット、数字、記号など128種類の文字に、0から127までの番号をふりました。
128種類なので、7ビットあれば表せます。実際には扱いやすさから8ビット(1バイト)を1文字に使うのが一般的です。
| 文字 | 10進数 | 16進数 | 2進数 |
|---|---|---|---|
| A | 65 | 41 | 01000001 |
| a | 97 | 61 | 01100001 |
| 0 | 48 | 30 | 00110000 |
| 空白 | 32 | 20 | 00100000 |
この並び方には工夫があります。数字の0〜9、大文字のA〜Z、小文字のa〜zが、それぞれ連続した番号になっているのです。おかげで、名前をあいうえお順(アルファベット順)に並べ替える処理が、単なる数値の大小比較で済みます。
さらに、大文字と小文字はちょうど32だけ離れています。32は2進数で100000なので、6桁目のビットを切り替えるだけで大文字と小文字を変換できます。
ASCIIは128文字しか表せません。ひらがな、カタカナ、漢字を含む日本語には、まったく足りません。常用漢字だけでも2000字以上あります。
そこで日本では、1文字に2バイト(16ビット)使う方式が作られました。2バイトあれば65,536種類を表せるので、漢字も収まります。ただし、複数の方式が並行して使われたことが、のちの混乱の原因になりました。
| 方式 | 特徴 |
|---|---|
| JISコード | 電子メールなどで使われた |
| Shift_JIS | Windowsで長く使われた日本独自の方式 |
| EUC-JP | UNIX系のシステムで使われた |
同じ「あ」という文字でも、方式によって違う数値が割り当てられています。これが文字化けを生みました。
国ごとに違う文字コードを使っていては、国際的なやり取りで必ず問題が起きます。そこで、世界中のあらゆる文字を1つの対応表にまとめようという試みが始まりました。それがUnicode(ユニコード)です。
Unicodeでは、漢字もアラビア文字もハングルも絵文字も、すべて同じ表の中に番号を持っています。現在では15万字以上が登録されています。
各文字の番号は、U+3042(「あ」)のように「U+」に続く16進数で表記します。この番号をコードポイントといいます。
Unicodeは番号を決めただけで、それをどうバイトの並びにするかは別に決める必要があります。その方式の一つがUTF-8で、現在ウェブページのほとんどがこれを使っています。
UTF-8の工夫は、文字によってバイト数を変える点にあります。
| バイト数 | 表せる文字 | 例 |
|---|---|---|
| 1バイト | ASCIIと同じ範囲 | A、0、記号 |
| 2バイト | ヨーロッパの文字など | é、Й |
| 3バイト | 日本語・中国語・韓国語 | あ、漢、한 |
| 4バイト | 絵文字、珍しい漢字 | 絵文字全般 |
英数字は1バイトのまま扱えるので、ASCIIで書かれた古いデータをそのまま読めます。この互換性が、UTF-8が広く普及した理由の一つです。一方で日本語は3バイト必要なので、同じ文字数でも英語よりデータ量が大きくなります。
文字化けの原因は、単純です。書いたときのルールと、読むときのルールが違うからです。
たとえば「情報」をUTF-8で書くと、6バイトの数値の並びになります。この数値を受け取った側が「1バイトが1文字だ」というルールで読むと、6文字の意味不明な記号として表示されます。データ自体は壊れていません。読み方が違うだけです。
上のツールで実際に確かめられます。同じ数値の並びが、読み方によってまったく違う見た目になることが分かります。
この問題を避けるため、HTMLファイルの先頭には必ず文字コードの宣言を書きます。
この1行が「このページはUTF-8で書かれています」とブラウザに伝えています。これがないと、ブラウザが推測で判断するため、文字化けが起きることがあります。