unicodeとutf-8についてのメモ
unicodeは世界の文字を収録した文字集合のことです。
個々の文字に対して番号が割り振られていて、その番号をコードポイントと呼びます。(21ビットで表現、実質3バイト必要)
コードポイントは16進数表示で頭にU+を付けて表現されます。
例:u+3042 'あ'
但しコードポイントは文字集合の中で文字の位置を表す通し番号であるため、コンピュータ外部との通信や保存にそのまま使われる訳ではありません。
他の機器との通信や外部記憶装置への保存のためには、一定のルールに従い通信等に支障のない文字コードに符号化(エンコード)する必要があります。
また逆に外部から読み込む際も復号化(デコード)する必要があります。
その符号化/復号化の方式はいくつか有りますが、UTF-8はそのうちの一つです。
符号化することで、制御文字以外の文字コードを表すバイト列の中に制御文字のビットパターンが現れないようにしています。これにより通信や機器における誤動作を防ぐことが出来ます。
CPUとメモリ内ではunicodeで処理し、外ではUTF-8等のコード体系で処理されるという形になっています。
UTF-8の各バイトのビットの意味
unicodeは21ビットを使うためバイト数では3バイトとなります。
UTF-8では1バイトから4バイトまでと可変長のバイト構造を使われています。
その為、utf-8は複数バイト列の先頭であるか、後続バイトかの区別が出来るようになっています。それを以下に16進数(Hex)とビット列で示します。
(ビット列のXは0か1に成り得るビットを表しています。)
HEX ビット列
00〜7F 0XXX XXXX 1byte文字 制御文字とASCII文字をそのまま割り当て
C0〜DF 110X XXXX 2Byte文字の先頭バイト
E0〜EF 1110 XXXX 3Byte文字の先頭バイト
F0〜F7 1111 0XXX 4Byte文字の先頭バイト
80〜BF 10XX XXXX 複数バイトの2バイト目以降のバイト
Xで示されるビットにunicodeのビットを対応させています。
具体例として'あ'の文字u+3042とUTF-8のE38182とのビット対応を示します。
図の中で色の付いている部分がunicodeに対して追加されたビット。
ubuntu上のPython3で確認してみる
Pythonで、utf-8で書き込まれたファイルtestkana.txtを読み込んで見ます。
testkana.txtの内容は次の通り、'あいうえお'の文字列です。
ubuntuのxxdコマンドでファイルを16進数でダンプしています。
確かにutf-8のコードになっています。
ord関数で16進数にしてみると確かにunicodeになっています。
コンピュータ(CPUとメモリ内)ではunicodeで扱うということです。