文字コード#
コンピューターはビットパターンを用いてさまざまなデータを表現する。文字も同様である。
学習目標#
エンコードとデコードの概念を理解する
ASCIIコードの仕組みを理解する
Unicodeの概要を理解する
エンコードとデコード#
文字をビットパターンで表現するには最も単純な方法は、各文字に対して一意のビットパターンを割り当てることである。
例えば,
文字 |
ビットパターン |
---|---|
A |
|
B |
|
C |
|
このように、文字をビットパターンに変換することをエンコード(encode)、ビットパターンから文字に戻すことをデコード(decode)と呼ぶ。
エンコードとは、情報を暗号化・記号化すること。
デコードとは、暗号化・記号化された情報を元に戻すこと。
– 大辞林(第二版)
\(N\)種類の文字を表現するには、\(N \leq 2^n\)を満たす最小の整数\(n\)を見つければよい。これは、\(n\)ビットのパターンを用いることで、\(N\)種類の文字を表現できるはずである。
例えば、128種類の文字を表現するには、最小で7ビットが必要である。
ASCIIコード#
ASCIIコードは、7ビットのパターンを用いて、128種類の文字を表現できる。
表現できるものは以下の通りである。
数字(0-9)
アルファベット(A-Z, a-z)
記号(! “ など)
制御文字(改行、タブなど)
Note
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種類の文字を表現できる。
Unicode#
Everyone in the world should be able to use their own language on phones and computers.
—Unicode
世界中のあらゆる文字表現に対応するために作られたのがUnicodeである。現在、Unicodeは文字の国際標準として広く使用されている。
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 |
Note
絵文字や一部の文字は、複数のコードポイントで構成される場合がある。
例えば、👍🏿は、👍と 🏿によって構成される。
ASCIIとの関係#
Unicodeは、ASCIIの128文字(U+0000〜U+007F)をそのまま含んでいる。
エンコード#
Unicodeは、文字を表現するためのさまざまなエンコーディング方式を提供している。標準的なエンコーディング方式には、UTF-8、UTF-16、UTF-32がある。この中では、UTF-8が最も広く使用されている。
UTF-32#
UTF-32は、各文字を32ビット(4バイト)で表現する。code pointを4 byteのビットパターンに変換するだけである。
例えば、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バイトとなる。
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でデコードしてみよう。
文字化け#
文字データが正しく表示できず、意味のない文字列が表示される現象を文字化けと呼ぶ。これは、エンコードとデコードの方式が一致しない場合に発生する。
文字化けが発生した場合は、適切な文字コードを指定してデコードする必要がある。
調べてみよう メモ帳、VSCode、Wordでは、どのように文字コードを指定するかを調べてみよう。