Ubuntu 18.04では、1つのUTF-8文字のみを含むダミーテキストファイルを作成しましたè
。他の文字はすべて次のとおりですascii
。
$ cat dummytext
Hello
Helloè
結果は次のとおりですhexdump
。
$ hexdump -C dummyfile
00000000 48 65 6c 6c 6f 0a 48 65 6c 6c 6f c3 a8 0a |Hello.Hello...|
0000000e
ファイルは次のように識別されます。
$ file dummyfile
dummyfile2: UTF-8 Unicode text
各文字はで表示されます。一つバイト、とは別にUTF-8è
文字、つまりc3a8
2バイトで表されます。各文字を表すために使用されるバイト数が一定でない場合、ファイルの内容を正しく解釈する方法は?
私の推測:おそらく、パーサーがascii
最後の文字よりも大きい16進値7F
(例c3
)を見つけた場合は、印刷する正しい文字を決定するために少なくとも別のバイトを読み取る必要がありますか?
答え1
BSDマニュアルセクション5のUTF8ページは次のとおりです。
説明する
UTF-8 エンコーディングは、UCS-4 文字を各文字に対して 1 から 6 までの数字を使用してオクテット シーケンスとして表します。これはASCIIと逆互換であるため、ASCII文字セットを参照してください
0x00
。0x7f
非ASCII文字のマルチバイトエンコーディングは、上位ビットセットを持つバイトのみで構成されています。実際のエンコーディングを下の表に示します。
[0x00000000 - 0x0000007f] [00000000.0bbbbbbb] -> 0bbbbbbb [0x00000080 - 0x000007ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb [0x00000800 - 0x0000ffff] [bbbbbbbb.bbbbbbbb] -> 1110bbbb, 10bbbbbb, 10bbbbbb [0x00010000 - 0x001fffff] [00000000.000bbbbb.bbbbbbbb.bbbbbbbb] -> 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb [0x00200000 - 0x03ffffff] [000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb [0x04000000 - 0x7fffffff] [0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb
値の複数の表現がある場合(例:
0x00
;; )0xC0 0x80
、0xE0 0x80 0x80
常に最短の表現が使用されます。長い文字は潜在的なセキュリティリスクを引き起こし、1:1の文字:オクテットシーケンスマッピングを損なうため、エラーとして検出されます。
セクション7のUTF8のLinuxのマニュアルページも同様に読みます。
説明する
[...場合によっては、UTF-8はUCS-2よりも優れています。部分的には、ほとんどのUNIXツールはASCIIファイルを必要とし、かなりの変更がなければ16ビットの単語を文字で読み取ることができないからです。 [...]
Unicode と UCS の UTF-8 エンコーディングは、このような問題を経験せず、UNIX スタイルのオペレーティング システムで Unicode を使用する一般的な方法です。
特性
UTF-8エンコーディングには、次の優れた特性があります。
- UCS文字
0x00000000
(既存のUS-ASCII文字)は、単にバイト(ASCII互換性)0x0000007f
でエンコードされます。これは、7ビットASCII文字のみを含むファイルと文字列がASCIIとUTF-8で同じエンコードを持つことを意味します。0x00
0x7f
したがって、実際にASCIIとUTF-8を区別することは不可能です。なぜなら、UTF-8ファイルではASCIIがはいUTF-8。 file
ファイルの最初の96KiBを見て、それが何であるかを確認してください。複数のUTF-8コードシーケンスが表示されるため、ファイルがASCIIの厳密な上位セットであるため、ファイルがUTF-8であると判断します。