47  文字コード

コンピューターはビットパターンを用いてさまざまなデータを表現する.文字も同様である.

47.1 学習目標

  • エンコードとデコードの概念を理解する
  • ASCIIコードの仕組みを理解する
  • Unicodeの概要を理解する

47.2 エンコードとデコード

文字をビットパターンで表現する最も単純な方法は,各文字に対して一意のビットパターンを割り当てることである.

例えば,

文字 ビットパターン
A 0000 0001
B 0000 0010
C 0000 0011

このように,文字をビットパターンに変換することをエンコード(encode),ビットパターンから文字に戻すことをデコード(decode)と呼ぶ.

エンコードとは,情報を暗号化・記号化すること.

デコードとは,暗号化・記号化された情報を元に戻すこと.

– 大辞林(第二版)

N 種類の文字を表現するには,N \leq 2^n を満たす最小の整数 n を見つければよい.これは,n ビットのパターンを用いることで,N 種類の文字を表現できるからである.

例えば,128種類の文字を表現するには,最小で7ビットが必要である.

2^7 = 128

47.3 ASCIIコード

ASCIIコードは,7ビットのパターンを用いて,128種類の文字を表現する文字コードである.ASCIIコードで表現できるものは以下の通りである.

  • 数字(0-9)
  • アルファベット(A-Z, a-z)
  • 記号(! ” など)
  • 制御文字(改行,タブなど)
ノートASCIIについて

ASCIIは,American Standard Code for Information Interchangeの略で,アスキーと読む.

ASCIIコード表をみると,各文字に対応する7ビットのパターンが確認できる.

コンピューターで扱うビット数は通常2の累乗であるため,実際には8ビット(1バイト)を用いてASCIIコードを表現する.左側のビットは0で埋められ,右側の7ビットがASCIIコードを表す.

下記は「Hello!」をASCIIコードで表現したものの一例である.

文字 ビットパターン 10進数
H 0100 1000 72
e 0110 0101 101
l 0110 1100 108
l 0110 1100 108
o 0110 1111 111
! 0010 0001 33

C言語では,文字はchar型で表現され,通常は1バイト(8ビット)を使用する.char型のデータを整数として出力すると,その文字のASCIIコードが表示される.

#include <stdio.h>

int main() {
    char c = 'A';
    printf("%d\n", c);
    return 0;
}

拡張ASCIIコード(Extended ASCII)では,8ビットを使用して256種類の文字を表現できる.

47.4 Unicode

Everyone in the world should be able to use their own language on phones and computers.

– Unicode

世界中のあらゆる文字表現に対応するために作られたのがUnicodeである.現在,Unicodeは文字の国際標準として広く使用されている.

47.5 Code Point

Unicodeは,各文字に一意のcode pointを割り当てる.code pointは,U+で始まり,16進数で表現される.

下はUnicodeの一部の文字とそのcode pointを示す.

文字 Code Point
A U+0041
U+3042
😂 U+1F602
π U+03C0
U+5B78
👍 U+1F44D
🏿 U+1F3FF
ノート絵文字とコードポイント

絵文字や一部の文字は,複数のコードポイントで構成される場合がある.

例えば,👍🏿は,👍と🏿によって構成される.

47.6 ASCIIとの関係

Unicodeは,ASCIIの128文字(U+0000〜U+007F)をそのまま含んでいる.

47.7 エンコード

Unicodeは,文字を表現するためのさまざまなエンコーディング方式を提供している.標準的なエンコーディング方式には,UTF-8,UTF-16,UTF-32がある.この中では,UTF-8が最も広く使用されている.

47.7.1 UTF-32

UTF-32は,各文字を32ビット(4バイト)で表現する.code pointを4バイトのビットパターンに変換するだけである.

例えば,Aのcode pointはU+0041であり,UTF-32では次のように表現される.

0000 0000 0000 0000 0000 0000 0100 0001

英数字だけを扱う場合,UTF-32はASCIIコードの4倍のメモリを使う.例えば,ASCIIコードで「Hello!」を表現する場合は,各文字が1バイト(8ビット)で表現されるため,合計6バイトとなる.一方,UTF-32では各文字が4バイトで表現されるため,合計24バイトとなる.

47.7.2 UTF-8

Code point UTF-8
U+0000〜U+007F 0xxxxxxx
U+0080〜U+07FF 110xxxxx 10xxxxxx
U+0800〜U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+010000〜U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8は,Unicodeのcode pointを1〜4バイトで表現する可変長エンコーディング方式である.ASCIIコードと互換性があり,ASCIIコードの文字はそのまま1バイトで表現される.

例えば,「學」のcode pointはU+5B78であり,2進数で表すと0101 1011 0111 1000となる.また,U+5B78は U+0800〜U+FFFF の範囲にあるため,1110xxxx 10xxxxxx 10xxxxxxの形式で表現される.code pointのビットパターンをUTF-8に変換するには,xの部分にビットを埋めていく.

「學」のUTF-8エンコードは次のようになる.

1110 xxxx -> 1110 0101
10xx xxxx -> 1010 1101
10xx xxxx -> 1011 1000

結果,UTF-8では次のように表現される.

11100101 10101101 10111000

これを16進数で表すと,E5 AD B8となる.こちらにアクセスして,E5 AD B8をUTF-8でデコードせよ.

47.8 文字化け

文字データが正しく表示できず,意味のない文字列が表示される現象を文字化けと呼ぶ.これは,エンコードとデコードの方式が一致しない場合に発生する.

文字化けが発生した場合は,適切な文字コードを指定してデコードする必要がある.

練習問題 メモ帳,VS Code,Wordでは,どのように文字コードを指定するかを調べよ.