UTF-8エンコードの文字数は"8","9","A","B"を除いて数えろ
きっと専門予備校では常識になっていると思いますが、
ざっとググっても出なかったので。
良く出てくるこの手の問題:
16進数表示された、次のUTF-8エンコード結果は、何文字のUnicode文字列をエンコードしたものか。
CF 80 E3 81 AF E7 B4 84 33 2E 31 34 E3 81 A7 E3 81 99
(応用情報・平成24年春季の概要)
10秒で正答へたどり着く技が、タイトルの通りです。
数え方
①各バイトデータの先頭が"8","9","A","B"で始まるものを消す。
CF 80 E3 81 AF E7 B4 84 33 2E 31 34 E3 81 A7 E3 81 99
②残ったバイト数を数える。
すると、残ったものは9バイトあるので、9文字が答えになります。
解説
UTF-8は、Unicodeを8ビット単位で符号化するためのフォーマットです。
元々、ASCIIの規格で表せなかった世界各国の文字を表そうとしたのがUnicodeですが、
- ASCIIが7ビットで表現されるのに対し、Unicodeは16ビットで表現される
- 互換性がない
という問題がありました。
これを解決させたのがUTF-8で、
- ASCIIにある文字は、ASCIIと同じように表し、先頭の1ビットは0とする。
- ASCIIにない文字は、6ビットごとに分割し、各6ビットごとの塊について、
- 最初の塊:11から始まるビット*1
- 2つ目以降の塊:10から始まるビットとする。
というルールでエンコードされます。
ところで、16進数と2進数の関係は
16進数 | 2進数 | 16進数 | 2進数 | |
0 | 0000 | 8 | 1000 | |
1 | 0001 | 9 | 1001 | |
2 | 0010 | A | 1010 | |
3 | 0011 | B | 1011 | |
4 | 0100 | C | 1100 | |
5 | 0101 | D | 1101 | |
6 | 0110 | E | 1110 | |
7 | 0111 | F | 1111 |
となっていますから、UTF-8のエンコードルールと照らし合わせると、
16進数 | 2進数 | UTF-8 | 16進数 | 2進数 | UTF-8 | |
0 | 0000 | ASCII文字 | 8 | 1000 | 非ASCII文字(2つ目以降) | |
1 | 0001 | ASCII文字 | 9 | 1001 | 非ASCII文字(2つ目以降) | |
2 | 0010 | ASCII文字 | A | 1010 | 非ASCII文字(2つ目以降) | |
3 | 0011 | ASCII文字 | B | 1011 | 非ASCII文字(2つ目以降) | |
4 | 0100 | ASCII文字 | C | 1100 | 非ASCII文字(先頭) | |
5 | 0101 | ASCII文字 | D | 1101 | 非ASCII文字(先頭) | |
6 | 0110 | ASCII文字 | E | 1110 | 非ASCII文字(先頭) | |
7 | 0111 | ASCII文字 | F | 1111 | 非ASCII文字(先頭) |
となります。
UTF-8の文字には、ASCII文字、非ASCII文字(先頭)、非ASCII文字(2つ目以降)の3種類しかなく、
Unicodeの文字数=ASCII文字の数+非ASCII文字の数
であり、また、
非ASCII文字の数=非ASCII文字の先頭の数
であるわけですから、
Unicodeの文字数=UTF-8の文字数−非ASCII文字(2つ目以降)
で答えが求まります。