Text-Processing

在同一文件中區分 ascii 和 UTF-8 字元

  • March 21, 2019

在 Ubuntu 18.04 上,我創建了一個只有一個 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字元的十六進制值7F(這是 的情況c3)時,被迫讀取至少另一個字節,以確定要列印的正確字元?

在 BSD 手冊第 5 節中,關於 UTF8 的頁面內容如下:

描述

UTF-8 編碼將 UCS-4 字元表示為八位字節序列,每個字元使用 1 到 6 個字元。它向後兼容 ASCII,所以0x00-0x7f請參閱 ASCII 字元集。

非 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 字元:八位字節序列映射。

在 Linux 手冊第 7 節中,有關 UTF8 的頁麵類似地寫道:

描述

$$ … UTF-8 is situationally better than UCS-2 in part because i $$此外,大多數 UNIX 工具都需要 ASCII 文件,如果不進行重大修改,就無法將 16 位字作為字元讀取。$$ … $$ Unicode 和 UCS 的 UTF-8 編碼不存在這些問題,是 Unicode 在 UNIX 風格的作業系統上使用的常用方式。

特性

UTF-8 編碼具有以下優點:

  • UCS 字元0x00000000to 0x0000007f(經典的 US-ASCII 字元)被簡單地編碼為字節0x00to 0x7f(ASCII 兼容性)。這意味著僅包含 7 位 ASCII 字元的文件和字元串在 ASCII 和 UTF-8 下具有相同的編碼。

所以實際上不可能區分 ASCII 和 UTF-8,因為在 UTF-8 文件中,ASCIIUTF-8。 file查看文件的前 96KiB 並嘗試確定它是什麼。因為它看到多個 UTF-8 程式碼序列,所以它確定文件為 UTF-8,因為它是 ASCII 的嚴格超集。

引用自:https://unix.stackexchange.com/questions/507782