UTF-32 和 UTF-16 的一个 Code Unit,须要转换成多个字节的序列,因而存在字节序的问题。
能够在 UTF-32 或 UTF-16 编码的字节流结尾,增加字节程序标记 (byte-order mark, BOM),来标识字节序。
BOM 是 U+FEFF
字符的名称。编码时,将 U+FEFF
编码在字节流的结尾。解码时,读取前几个字节,就晓得编码时的字节序了。
例如 UTF-16 的大端序,U+FEFF
会被编码成 0xFEFF
,而小端序则会编码成 0xFFFE
。这样依据结尾是 0xFEFF
还是 0xFFFE
,就晓得编码时应用的大端序还是小端序了。
同理 UTF-32 的大端序,U+FEFF
会被编码成 0x00 00 FE FF
,而小端序则会编码成 0xFF FE 00 00
。这样依据结尾,不光能辨别出字节序,还能辨别出是 UTF-32 还是 UTF-16。
UTF-8 的一个 Code Unit 只须要转换为 1 个字节,因而不存在字节序的问题,也就不须要 BOM。而且 0xFEFF
或 0xFFFE
字节序列,在 UTF-8 中都是不可能呈现的。所以依据 BOM,也能辨别出编码方式是不是 UTF-8。
如果硬要给 UTF-8 加 BOM,那就是将 0xFEFF
(0b1111 1110 1111 1111
) 进行 UTF-8 编码,失去 0xEF BB BF
(0b1110 1111 1011 1011 1011 1111
),放在字节流的最后面。
之所以应用 U+FEFF
这个字符来标识字节序,可能是因为这个字符自身就示意“零宽非断空格”的含意。把他放在最后面,解码的时候反对 BOM,就把他依照字节序去了解;不反对的就把他解析成一个“零宽非断空格”,展现起来也没有任何影响。当然这是我瞎猜的,而且从 Unicode 3.2 开始,U+FEFF
曾经专门用来标记字节序,没有其余含意了。
相干文章:
- 字节序
- 详解字符编码与 Unicode