「文字の番号」と「保存するバイト列」は別のもの
画面に見える「A」や「あ」を、その形のまま計算機に保存することはできません。内部で扱えるようにするには、まず文字を番号に対応させ、さらにその番号をビットの並びに変換する必要があります。この二段階を区別すると、文字コードの仕組みが見通しやすくなります。
Unicodeは、世界で使われる多くの文字や記号を共通に扱うための規格です。Unicodeでは、それぞれの文字に「コードポイント」と呼ばれる番号を割り当てます。コードポイントは通常、U+に16進数を続けて表し、たとえば「A」はU+0041です。これは文字を識別する番号であり、そのままファイルに並ぶバイト列を示しているわけではありません。
コードポイントを実際のバイト列へ変換する規則が、UTF-8やUTF-16などの符号化方式です。同じUnicodeの文章でも、どの符号化方式を選ぶかによってファイル内のバイト列は変わります。番号を0と1で表す基本は二進法と同じですが、何ビットずつ、どの順序で記録するかまで共有して初めて、元の文字を復元できます。
UTF-8で「あ」を送って表示するまで
文章をUTF-8で保存するとき、ソフトウェアは各文字のコードポイントをUTF-8の規則に従うバイト列へ変換します。そのファイルを別の機器で開くと、今度はバイト列をUTF-8として読み取り、コードポイントへ戻します。最後にフォントが、そのコードポイントに対応する字形を画面へ描きます。
ここには、文字の意味を決める規格、データの並べ方、見た目を描くフォントという異なる役割があります。文字コードが同じでも、利用するフォントが違えば字の形は少し変わります。また、フォントに対応する字形がなければ、四角い記号などで代替表示されることがあります。文字の番号が失われたとは限りません。字形には輪郭で表すものや点の集まりで表すものがあり、これはラスタ形式とベクタ形式にもつながる話です。
通信でも、送る側と受け取る側が符号化方式を正しく共有する必要があります。Webページでは文書の文字エンコーディングを示す情報を付け、ブラウザがどの規則でバイト列を読むか判断できるようにします。このように双方で解釈の規則を合わせる点は、通信手順を定めるプロトコルと共通しています。
文字化けは「データが別の文字に読み替えられた」状態
UTF-8で作ったバイト列を、別の符号化方式だと思って読み取ると、本来とは異なる文字や記号が表示されます。これが文字化けの典型です。保存時の変換規則と、読込時の復元規則が食い違っているために起こります。表示だけが誤っていて元のバイト列が保たれている場合は、正しい方式を指定して読み直せば復元できることがあります。
ただし、文字化けした表示をそのまま保存し直したり、変換先に存在しない文字を代替記号へ置き換えたりすると、元の情報が失われる場合があります。対策の基本は、推測で何度も変換することではなく、元データを残したうえで、作成時の符号化方式を確認することです。ファイル、Webページ、データベース、プログラムの各段階で同じ前提を使うことも重要です。
改行やタブも、データ中では制御のための符号として扱われます。そのため、文章の見た目だけを見ても、内部にどのような符号が含まれているかを完全には判断できません。検索や集計の前に文字データの形式をそろえる作業は、テキストマイニングの結果を安定させるうえでも欠かせません。
見た目が同じでも内部の並びが同じとは限らない
Unicodeでは、見た目がよく似た文字でも、意味や由来が異なれば別のコードポイントになっていることがあります。たとえば、半角と全角の英数字は別の文字として区別されます。人間には同じ語に見えても、コンピュータによる検索、並べ替え、文字数の判定では一致しない場合があります。
また、アクセント付き文字などには、一つのコードポイントで表す方法と、基になる文字と記号を組み合わせて表す方法が用意されているものがあります。表示結果が同じように見えても、内部のコードポイント列は同一とは限りません。この違いを一定の形へそろえる処理をUnicode正規化といいます。
正規化には目的の異なる方式があるため、すべての文章を無条件に一つの形へ変えればよいわけではありません。利用するシステムの仕様に合わせ、元の表記を区別すべきデータかどうかを考える必要があります。文字コードは単なる表示設定ではなく、照合や検索の正確さにも関わるデータ設計の一部です。
UTF-8の中にもASCIIが生きている
UTF-8では、ASCIIで定められた英字、数字、基本的な記号などの範囲が、ASCIIと同じ1バイトの値で表されます。この互換性により、ASCIIだけで書かれたデータはUTF-8としても同じ内容に解釈できます。一方、日本語を含む文字は複数バイトで表されます。UTF-8の「8」は、すべての文字を8ビット一つで表すという意味ではなく、8ビット単位の並びを使うことを示しています。
この性質は、英数字を多く使うプログラムや通信データを扱いやすくしながら、多様な文字も同じ方式で扱えることにつながっています。ただし、UTF-8を選んだだけで、どの環境でも必ず同じ見た目になるわけではありません。対応するフォント、正規化の方法、改行の扱いなどは別に確認が必要です。「文字を識別する番号」「番号を記録する方式」「文字を描く形」を分けて考えることが、文字に関する不具合を切り分ける近道です。