UTF-8とは、Unicodeの文字符号化形式/文字符号化方式の一つである。
概要
UTF-8とは、Unicodeの文字符号化形式/文字符号化方式の一つで、1文字は1〜4バイトのバイト列で表現される。最大の特長は、英数字(ASCII文字)だけの場合はASCIIと完全互換(というか完全に一致)になることである。
Unicodeの表現形式として広く用いられており、デファクトスタンダードであるとも言える。
長所
- 英数字(ASCII文字)だけの場合はASCIIと全く同じ。従って英語圏ではASCIIを想定して作られた過去のプログラムがそのままUTF-8対応として通用する(ただし、複数バイト文字が来たら壊れる)。
- 英数字中心の場合はデータ量が少なくて済む。UTF-16やUTF-32は英数字もそれぞれ2バイト、4バイトで表現するので、データ量が2倍、4倍になる。
- 文書データ(特にHTML)は本文のテキスト以外にもタグなどのメタデータを大量に英数字で保有していることが多く、総合的に見ると英数字が1バイトで記述できる方がデータ量が少なくなる。
短所
- 文字のバイト数が固定長であれば、n文字目の文字を取り出したい時に、n文字目が先頭から何バイト目から始まるか計算可能なので、すぐにアクセスできるが、UTF-8は文字のバイト数が可変長なので、先頭から順番に文字数を数えなくてはならない。
- 同様に文書の文字数を知りたい時も先頭から末尾まで走査しなければならない。
- 実は日本語の場合、UTF-8だとひらがな・カタカナ・漢字が3-4バイト文字になるので、使用頻度の低い一部の漢字以外は2バイトで表現できるUTF-16の方がデータ量は少なくて済む。
ただ、これらの長所・短所もコンピューターの性能向上や大容量化、あるいはデータ構造の工夫等により問題になる場面は少なくなっている。実際の所、みんながUTF-8を標準で使うようにすればもう文字コードや文字化けで悩まなくてもいいよね、という側面が大きい。
詳細
1バイトを0と1に直した時、先頭からいくつ1が連続するかでそのバイトの役割が決まる。
- 0(0xxxxxxx) → 1バイト文字
- 1(10xxxxxx) → 2バイト目以降
- 2(110xxxxx) → 2バイト文字の1バイト目
- 3(1110xxxx) → 3バイト文字の1バイト目
- 4(11110xxx) → 4バイト文字の1バイト目
- 5以上(11111xxx) → UTF-8では使われない。
0-31, 127 | 制御文字 | |
32-126 | 英数記号 | |
128-191 | 2バイト目以降 | |
192-193 | 不使用(2バイト文字先頭) | |
194-223 | 2バイト文字先頭 | |
224-239 | 3バイト文字先頭 | |
240-244 | 4バイト文字先頭 | |
245-247 | 不使用(4バイト文字先頭) | |
248-255 | 不使用(5バイト以上相当) |
1バイト文字
ASCIIは7ビット、つまり0-127(00-7F)だが、0-31と127は制御文字であり、改行コードなどを除けば通常のテキストでは使用されない。
残りの32-126はアルファベットの大文字・小文字、数字と各種記号である。 → ASCII
2バイト文字
2バイト以上の文字は、先頭に使用バイト数を決めるデータが来て、後ろにデータが続く。2バイト目以降には128-191(80-BF)が使われるが、先頭の2ビットは10で固定なので残りの6ビットがデータ部分となる。
2バイト目の先頭バイトは194-223(C2-DF)である。先頭の3ビットが110で固定なので、5ビットがでデータ部分となり、2バイト目の6ビットと合わせて11ビットまでのUnicodeが表現可能である。
最小バイト数の原則
C0とC1(192-193)は、データ部分のビットが00000と00001であり、2バイト目の6ビットと合わせても、7ビット(1バイト文字)で表現可能である。Unicodeには最小バイト数で表現しなければならないという原則があるため使用されない(故意に冗長なバイト列にしてセキュリティチェックをすり抜ける問題が発生したためルールが追加された)。
3バイト文字
3バイト文字の先頭バイトは224-239(E0-EF)である。先頭4ビットが1110で固定のため、残り4ビットと2-3バイト目の6×2ビットで16ビットまでのUnicodeが表現可能である。
最小バイト数の原則により、11ビットまでで表現可能なものは除かれるので、2バイト目は11-6=5ビットよりも多いビット数を使用する必要があり、1010 0000(2) 以上でなければならないため、160-191(A0-BF)に限られる。
4バイト文字
4バイト文字の先頭バイトは240-244(F0-F4)である。先頭5ビットが11110で固定のため、残り3ビットと2-4バイト目の6×3ビットで21ビットまでのUnicodeが表現可能である。
最小バイト数の原則により、16ビットまでで表現可能なものは除かれるので、2バイト目は16-6×2=4ビットよりも多いビット数を使用する必要があり、1001 0000(2) 以上でなければならないため、144-191(90-BF)に限られる。
Unicodeの上限値はU+10FFFF(1 0000 1111 1111 1111 1111(2))である。245-247(F5-F7)はデータ部分が101-111であり2バイト目以降の18ビットと合わせるとUnicodeの上限値を超えるため使用されない。
5バイト文字以上
5バイト文字と6バイト文字は先頭バイトをそれぞれ248-251(F8-FB)、252-253(FC-FD)にすれば実現可能だが、やはり最小バイト数の原則に反するかUnicodeの上限値を超えるため使用されない。
254-255(FE-FF): 7-8バイト文字も、5-6バイト文字と同じく使用されない。UTF-16やUTF-32のバイトオーダーマークで使用されるため、ファイルの先頭に出てきた場合は、UTF-8ではなく、UTF-16やUTF-32であろうということになる。
バイトオーダーマーク
テキストファイルの先頭にU+FEFF: ZERO WIDTH NO-BREAK SPACE (ZWNBSP) を付加することができ、BOM(Byte Order Mark)と呼ばれる。Byte Orderというのはデータを上位バイトから順に並べるビッグエンディアンと下位バイトから並べるリトルエンディアンの区別のことだが、データを先頭の2-4バイトを読むだけで符号化方式が分かるようにする仕組みも兼ねている。
UTF-8では使用が許容されるというだけで推奨ではない。むしろASCIIとの互換性が損なわれるので、Unicodeの仕様上では許容されているにも関わらず、対応していない処理系も多いというのが現実である。
そもそもUTF-8にはリトルエンディアンはない。
ちなみにUTF-8のBOMはEF BB BF(239 187 191)である。これを2進数に変換すると、
であり、1110から始まるので3バイト文字だと分かる。さらにデータ部分を抜き出すと
1110 1111 | 1011 1011 | 1011 1111 | |
1111 | 11 1011 | 11 1111 | |
1111 1110 | 1111 1111 | ||
FE | FF |
ちなみに、U+FEFF: ZERO WIDTH NO-BREAK SPACE (ZWNBSP) は、元々は改行禁止を表す零幅文字である。
メモ帳問題
Windowsのメモ帳はBOMなしUTF-8の編集時に勝手にBOMを付加することで悪名高かったが、Windows 10の2019年5月のメジャーアップデートからBOMなしUTF-8がデフォルトになった。
英数字だけだとASCIIと完全に一致するので、ASCIIだと思って解釈していたら突然2バイト文字が出てきてバグったなどという事態を避けるため、区別できるようにしようと思ったらBOMをつけるしかなかったのかもしれない。
もしくは、ExcelがBOMの無いUTF-8のCSVを読み込むと正しく解釈できないのに引き摺られたか。
関連項目
- Unicode / UTF-16 / UTF-32
- ASCII / 文字コード
- ビット / バイト / 2進数 / 16進数
- 文字化け
- バイトオーダーマーク(BOM) / ZERO WIDTH NO-BREAK SPACE
- メモ帳
- i18n / l10n
- プログラミング関連用語の一覧
- 4
- 0pt