アフィリエイターの 技術的な疑問やお悩みに お答えします!

サイト運営やプログラム作成していると時々、UTF-8やShift-JISという言葉を聞くことがある。
いわゆる文字コードというものだが違いが気になった僕は、少し調べてみることにした。

文字コードは実際に調べてみると、非常に難解。
そこで今回は、学習の足掛かりとして単純化してお伝えする。

文字コードとは

Webサイト作成に軽くかかわっている人は、文字コードと聞くとShift-JISやUTF-8などを思い浮かべると思う。
プログラマーやシステム管理者はそれに加えて、ASCIIコードやUnicodeを思い浮かべる。

しかし調べてみると、これら全てを同じ枠組みとして扱ってはいけないようだ。

これらは、次の二つに分類することができる。

  1. 符号化文字集合:
    文字に番号を振ったもの。コンピュータ内部で使用する
    代表的な例:ASCIIコード、Unicode

  2. 符号化形式:
    番号をファイルに保存したり、ネットワーク間で転送させるための形式
    代表的な例:Shift_JIS、UTF-8

このように文字コードとして認識していたものは、2つの分類がごちゃごちゃになっていたようだ。

符号化文字集合

文字はアルファベットや数字、ひらがなカタカナ漢字など非常に多くの種類がある。
しかしコンピューターは、文字そのものを理解しているわけではない。

文字は一つ一つ番号が振られている。
例えば「A」を1、「!」を10、「あ」を100、「い」を101などだ。

コンピューターに文字を表示したいときは、その番号で指示を出す。
コンピューターはその番号に対応するフォントを探してきて、ディスプレイに表示する。
つまり、コンピューターは「あ」ではなくて100に対応するものを表示しているだけなのだ。

符号化文字集合 画面表示

この文字に何番を割り当てるかということを定めたものが、符号化文字集合や単に文字セットと呼ぶ。
文字という人の頭の中にある情報に番号という符号を当てはめた集まりなのだ。

ただし符号化文字集合にはいくつかの種類があり、コンピューター内で同居している。

符号化文字集合

しかも、同じ文字が複数の符号化文字集合内に存在するケースがある。

ディスプレイに表示するときは、どの符号化文字集合の何番かを指示する必要があるのだ。

代表的な符号化文字集合をいくつかピックアップしてみる。

ASCII

コンピューター業界の初期に定められた規格。
アルファベットや数字・記号などのキーボードで日本語変換しないで入力できる文字や、改行コードなどの制御文字が番号0から127までに割り当てられている。
古参プログラマーにはなじみ深いコードである、かもしれない。

ASCIIコード表

JIS X 0201

JISという名前からわかるとおり、日本で制定した規格。

基本的にASCIIの流用だが、バックスラッシュ文字が円記号に、チルダがオーバーラインに置き換わっている。
また128から255までに半角カタカナが割り当てられている。

JIS X 0201コード表

JIS X 0208

こちらも、日本で制定した規格。
ひらがな・カタカナ・漢字だけでなく全角の数値や記号・罫線も定義されている。

実際には連番ではなく区番号と点番号の組み合わせで定義されていている。

例:「あ」 区4 点2 「い」 区4 点4

この他にも補助漢字を定義したJIS X 0212や、JIS X 0208を拡張したJIS X 0213というものがあるようだが、とりあえずはJISが制定した日本語向け規格があることを知っておく程度で大丈夫。

一部の番号においてWindowsとMacでは、割り当てられている文字が異なるという問題がある。
いわゆる「機種依存文字」と呼ばれるものだ。

Unicode

世界中の文字を全て詰め込もうとして制定した規格。
日本語や絵文字も含まれている。

現在は、これが主流。

符号化形式

符号化形式は、符号化文字集合で決めた番号をコンピューター上で記憶する方法を定めたものだ。

符号化文字集合は単なる番号だ。

この番号をファイルに保存したり、ネットワーク間で転送したりする際に、いろいろ取り決めをする必要がある。
たとえば、一文字何バイトで保存するかなどだ。
これを決めておかないと、どこまでが一文字がわからなくて困ってしまう。
その際、できるだけデータ量が少なくなると嬉しい。
そのためには、少し複雑な計算も許容される。

符号化文字集合で割り当てた番号をファイルに保存したり、ネットワーク間で転送したりしやすい形式に変換する。
または変換したデータを番号に戻す。
その取り決めが、符号化形式だ。

またはエンコーディングルールとも呼ばれる。
ブラウザなどでテキストエンコーディングという言葉が使われるが、これと同じだ。

符号化形式にもいくつか種類があるので代表的なものを挙げてみる。

Shift_JIS

JIS X 0201とJIS X 0208に対応した、符号化形式。

JIS X 0201はそのまま1バイトデータで扱われる。
JIS X 0208は、区と点を各1バイト、計2バイトで表す。ただし第一バイト(区)は計算により、JIS X 0201の空き領域(16進数で81から9FまたはE0からEF)へ、第二バイト(点)は16進数で40から7Eまたは80からFCにシフトされる。

! X Y Z ア(半カナ) イ(半カナ) CR LF
21 58 59 5A 82 A0 82 A2 B1 B2 0D 0A

JIS X 0208には機種依存文字という問題があるということにふれたが、それをもとにしているShift_JISも影響を受ける。
Shift_JISで文書を作成するときは、機種依存文字を使用しないことが望ましい。

またUnicodeに含まれている絵文字😍などを使用した場合、Shift_JISで保存すると情報が失われる。

なお、ASCIIコードの対応する文字(127以下)のみをShift_JISで保存した場合、後述のUTF-8と同じデータとなる。

UTF-8

Unicodeに対応した、符号化形式。
1文字の番号を8ビット(1バイト)単位に分割する。

計算例:

  1. 「あ」の番号は16進数で3042
    2進数にすると、0011000001000010
  2. 先頭の0を除いたビット数は14
  3. 7ビット以下なら、そのまま使用→ASCII文字は変換せずそのまま使用される
  4. 下位ビットから6ビット単位で分割
    11 000001 000010
  5. 最上位以外に次のように10を付加して8ビットにする
    11 10000001 10000010
  6. 最上位バイトの先頭(8ビット目)から、最上位バイトを含めたバイト数個のビット1と、0を付加
    11100011 10000001 10000010

    ※元からある1と重なるときは、バイト数を増やして調整する。
    11111 10000001 10000010のとき、
    111011111 10000001 10000010
    になり、最上位が9ビットになる。
    次のように調整する。
    11110000 00011111 10000001 10000010
  7. 16進数にする
    11100011 10000001 10000010
    →E3 81 82
! X Y Z ア(半カナ) イ(半カナ) CR LF
21 58 59 5A E3 81 82 E3 81 84 EF BD B1 EF BD B2 0D 0A

BOMとは

Windowsのメモ帳などでテキストをUTF-8で保存するとき、BOMを付加する選択肢がある。
メモ帳 UTF-8 BOM

BOMを指定すると、ファイル(データ)の先頭にUTF-8でエンコードされることを表すデータEF BB BFが付加される。

! X Y Z ア(半カナ) イ(半カナ) CR LF
EF BB BF 21 58 59 5A E3 81 82 E3 81 84 EF BD B1 EF BD B2 0D 0A

BOMがあると正常に動作しないケースもあるので、明確な目的がある場合以外は使用しない方が無難。

UTF-16

Unicodeに対応した、符号化形式。
1文字の番号を16ビット(2バイト)単位に分割する。
ただし、16進数で10000以上の文字は32ビット(4バイト)に変換される。

計算例:

  1. 絵文字「🦔」の番号は16進数で1F994
  2. 10000未満なら、そのまま使用→結果は16ビット(2バイト)
    ※普通の文字は2バイトになる
  3. 1F994から10000を引く
    1F994 - 10000 = F994
  4. F994を2進数にすると、1111100110010100
  5. 下位から10ビット目で分割。上位も10ビットになるように0を補完する

    0000111110 0110010100

  6. 次のように上位に110110。下位に110111を付加。

    1101100000111110 1101110110010100

  7. 16進数にする
    11011000 00111110 11011101 10010100
    →D8 3E DD 94

※4バイト変換時、上下各2バイトに分割したペアをサロゲートペアと呼ぶ。

BEとLE

Windowsのメモ帳でUTF-16は、BEとLEの種類から選択できる。

Windowsのメモ帳 UTF-16 BE LE

これについて、簡単に説明してみる。

2バイト以上のデータは通常上位バイトを先に記述する。
しかし、下位バイトから記述することがある。
どちらを先にするかをエンディアン(Endian)と呼ぶ。

さらに、上位バイトから順番に並べるエンディアンをビッグエンディアン(BE)。
下位バイトから順番に並べるエンディアンをリトルエンディアン(LE)と呼ぶ。

例えば16進数で、ABCDEF1234というデータがあるとする。
AB CD EF 12 34 と並べたものが、ビッグエンディアン。
34 12 EF CD AB と逆順に並べたものがリトルエンディアンだ。

■UTF-16 BEのデータ

データの先頭に、BOMとして「FE FF」が付与される

! X Y Z ア(半カナ) イ(半カナ) 🦔 CR LF
FE FF 00 21 00 58 00 59 00 5A 30 42 30 44 FF 71 FF 72 D8 3E DD 94 00 0D 00 0A

■UTF-16 LEのデータ

データの先頭に、BOMとして「FF FE」が付与される
サロゲートペアは2バイトデータが二つとして取り扱われるので、2バイト単位で上下を反転させる。

! X Y Z ア(半カナ) イ(半カナ) 🦔 CR LF
FF FE 21 00 58 00 59 00 5A 00 42 30 44 30 71 FF 72 FF 3E D8 94 DD 0D 00 0A 00
ASCIIコードの対応する文字(127以下)のみをUTF-16保存した場合、BOMを除いたデータ数はUTF-8の2倍となる。
UTF-16とは別に、UTF-16BEとUTF-16LEという符号化形式がある。
この二つは形式名としてBEまたはLEが入っているので、「FE FF」や「FF FE」をデータの先頭に付与しない。

htmlはUTF-8が望ましい

htmlデータは、タグが多く使用されている。
タグはASCIIコード内の文字で構成されているため、UTF-16よりもUTF-8で保存したほうが、データ量が少なくなる。
日本語に関しては基本的にUTF-8が3バイト、UTF-16が2バイトとUTF-16の方が有利だが、WordPressなどでサイトを作成した場合、タグ文字の方が日本語よりも多くなりやすい。

Shift_JISに関しては機種依存文字などの問題があり、Webサイト向けの符号化形式としてはおススメできない。

Webサイト向けの符号化形式は、UTF-8が望ましい。

関連記事: