【问题标题】:Byte Order Mask: confusing the UTF encoding字节顺序掩码:混淆 UTF 编码
【发布时间】:2018-04-08 23:41:47
【问题描述】:

字节顺序掩码 (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 且带有字符 U+EFBB 和 U+BF40 (EF BB BF 40) 的 UTF-16 大端编码文件,它会与带有 BOM 的 UTF-8 编码文件混淆吗和 ASCII 字符 @?

【问题讨论】:

    标签: unicode utf-8 utf-16 byte-order-mark


    【解决方案1】:

    当然,在不知道编码的情况下,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 的字节并没有太大变化。如果您首先知道文件是具有 Unicode 编码之一的文本文件,那么是的,如果存在 BOM,您可以使用它来区分 Unicode 编码。但是,很难想象你什么时候会拥有所有这些知识,但也不知道它是哪种编码(因此不需要 BOM 来实现 目的)。
    • 没有。 BOM 让编码库被告知编码是 UTF-16 或 UTF-32,并且它可以检测 BOM 中的字节顺序。
    • 是的,如果您有“一个 UTF-16 大端编码文件”,请告诉您将文件提供给谁;那么他们就不必通过使用 UTF-8 阅读来询问或尝试猜测。
    • 正如我所说,一般来说,没有通用的解决方案。有一些特定类型的文本文件(JSON、HTML、XML)具有解决这些问题的标准(当然,还有许多其他非文本文件)。如果您的用户愿意使用文本文件但不愿意指明他们选择的编码,他们为什么会符合您的期望,即它是 Unicode 编码之一?
    【解决方案2】:

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

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

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

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

    控制字符和私有字符集不应用于“公共”Unicode 文本(但如果您同意协议,那么问题就不应该如此)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      相关资源
      最近更新 更多