字节顺序掩码:混淆 UTF 编码



字节顺序掩码 (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 编码混淆?

例如,如果我有一个没有 BOM 的 UTF-16 大端编码文件,并且字符为 U+EFBB 和 U+BF40 (EF BB BF 40),它会与带有 BOM 和 ASCII 字符@的 UTF-8 编码文件混淆吗?

当然,在不知道编码的情况下,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  

BTW - 看起来像字节顺序标记的字节不能用于确定文本文件的编码。一般来说,这是一个无法解决的问题——数据丢失。

BOM 设计用于在已知大小时查找字节顺序。所以没有U+FFFE代码。 对字符集没有进一步的限制,因此可以有一些重叠的代码。(@TomBlodget有一个"退化"案例的例子)

UTF-8 中的 BOM 并不是真正需要的,但应该保留它,以便从其他 unicode 编码进行完美的圆形转换。只是Windows开始使用它将UTF-8与其他编码(尤其是Unicode编码之外)区分开来,并且它不是100%可靠的。

C0C1是 UTF-8 上不允许的字节,沿着各种序列(字节 1 上的第一个位定义了序列的长度,因此应该有这么多带有"延续前缀"(0b10的字节)。所以通常很容易找到一个字符串是否是 UTF-8(如果不是太短或"退化")。

UTF-32 的有效值仅从0U+10FFFF,因此这可以用来将其与 UTF16 区分开来(同样,"退化"和短字符串是不可区分的,OTOH 我们应该期望在 UTF32 中经常00 00,通常 UTF16普通文本没有00 00,但最后是 ev.)。

控制字符和私有字符集不应该用于"公共"Unicode文本(但如果你同意协议,但不应该是问题的情况)。

最新更新