字节顺序掩码:混淆 UTF 编码
Byte Order Mask: confusing the UTF encoding
字节顺序掩码 (BOM) 使用 Unicode 字符 U+FEFF 根据以下规则确定文本文件的编码:
+-------------+-----------------------+
| Bytes | Encoding Form |
+-------------+-----------------------+
| 00 00 FE FF | UTF-32, big-endian |
| FF FE 00 00 | UTF-32, little-endian |
| FE FF | UTF-16, big-endian |
| FF FE | UTF-16, little-endian |
| EF BB BF | UTF-8 |
+-------------+-----------------------+
我的问题是:是否有任何字节组合可以使一种 UTF 编码与另一种 UTF 编码混淆?
例如,如果我有一个 UTF-16 大端编码文件,没有 BOM,但带有字符 U+EFBB 和 U+BF40 (EF BB BF 40),它会与 UTF-8 编码文件混淆吗带 BOM 和 ASCII 字符 @
?
当然,在不知道编码的情况下,U+0000 个字符的序列长度未知。
00 00 00 00 UTF-8 U+0000 U+0000 U+0000 U+0000
00 00 00 00 UTF-16 U+0000 U+0000
00 00 00 00 UTF-32 U+0000
顺便说一句——看起来像字节顺序标记的字节不能用于确定文本文件的编码。一般来说,这是一个无解的问题——数据丢失。
BOM 设计为在已知大小的情况下查找字节顺序。所以没有U+FFFE
代码。字符集没有进一步的限制,所以可以有一些重叠的代码。 (@TomBlodget 有一个 "degenerate" 案例的例子)
UTF-8 中的 BOM 并不是真正需要的,但应该保留它,以便从其他 unicode 编码进行完美的轮转换。刚刚Windows开始用它来区分UTF-8和其他编码(尤其是unicode编码之外),而且它不是100%可靠的。
C0
和 C1
是 UTF-8 不允许的字节,沿着各种序列(字节 1 的第一位定义序列的长度,所以应该有这么多字节"continuation prefix" (0b10
)。所以通常很容易找到一个字符串是否是UTF-8(如果不是太短或"degenerate")。
UTF-32 具有从 0
到 U+10FFFF
的有效值,因此这可以用来将它与 UTF16 区分开来(同样,"degenerate" 和短字符串不可区分, OTOH 我们应该经常在 UTF32 中期待 00 00
,并且在 UTF16 正常 文本中通常没有 00 00
,但最后是。)。
不应在 "public" Unicode 文本上使用控制字符和私有字符集(但如果您同意该协议,则不应出现这种情况)。
字节顺序掩码 (BOM) 使用 Unicode 字符 U+FEFF 根据以下规则确定文本文件的编码:
+-------------+-----------------------+
| Bytes | Encoding Form |
+-------------+-----------------------+
| 00 00 FE FF | UTF-32, big-endian |
| FF FE 00 00 | UTF-32, little-endian |
| FE FF | UTF-16, big-endian |
| FF FE | UTF-16, little-endian |
| EF BB BF | UTF-8 |
+-------------+-----------------------+
我的问题是:是否有任何字节组合可以使一种 UTF 编码与另一种 UTF 编码混淆?
例如,如果我有一个 UTF-16 大端编码文件,没有 BOM,但带有字符 U+EFBB 和 U+BF40 (EF BB BF 40),它会与 UTF-8 编码文件混淆吗带 BOM 和 ASCII 字符 @
?
当然,在不知道编码的情况下,U+0000 个字符的序列长度未知。
00 00 00 00 UTF-8 U+0000 U+0000 U+0000 U+0000
00 00 00 00 UTF-16 U+0000 U+0000
00 00 00 00 UTF-32 U+0000
顺便说一句——看起来像字节顺序标记的字节不能用于确定文本文件的编码。一般来说,这是一个无解的问题——数据丢失。
BOM 设计为在已知大小的情况下查找字节顺序。所以没有U+FFFE
代码。字符集没有进一步的限制,所以可以有一些重叠的代码。 (@TomBlodget 有一个 "degenerate" 案例的例子)
UTF-8 中的 BOM 并不是真正需要的,但应该保留它,以便从其他 unicode 编码进行完美的轮转换。刚刚Windows开始用它来区分UTF-8和其他编码(尤其是unicode编码之外),而且它不是100%可靠的。
C0
和 C1
是 UTF-8 不允许的字节,沿着各种序列(字节 1 的第一位定义序列的长度,所以应该有这么多字节"continuation prefix" (0b10
)。所以通常很容易找到一个字符串是否是UTF-8(如果不是太短或"degenerate")。
UTF-32 具有从 0
到 U+10FFFF
的有效值,因此这可以用来将它与 UTF16 区分开来(同样,"degenerate" 和短字符串不可区分, OTOH 我们应该经常在 UTF32 中期待 00 00
,并且在 UTF16 正常 文本中通常没有 00 00
,但最后是。)。
不应在 "public" Unicode 文本上使用控制字符和私有字符集(但如果您同意该协议,则不应出现这种情况)。