所以我自学了字符编码,我有一个可能是愚蠢的问题:Wikipedia说
字节顺序标记(BOM)是Unicode字符,U + FEFF BYTE ORDER MARK(BOM),......
,该页面上的图表写了
Encoding Representation (hexadecimal)
UTF-8 EF BB BF
UTF-16 (BE) FE FF
UTF-16 (LE) FF FE
...
我有点困惑。据我所知,大多数使用Intel CPU的机器都是little-endian,为什么BOM为U+FE FF
为UTF-16(BE),而不是U+EF BB BF
为UTF-8或U+FF FE
为UTF -16(LE)?
答案 0 :(得分:3)
据我所知,大多数使用Intel CPU的机器都是little-endian
Intel CPU并不是世界上唯一使用的CPU。 AMD,ARM等等还有大端CPU。
为什么BOM是UTF-16(BE)的U + FE FF,而不是UTF-8的U + EF BB BF或UTF-16(LE)的U + FF FE?
U+FEFF
是Unicode代码点名称。 FE FF
,EF BB BF
,FF FE
,这些是字节序列。 U+
仅适用于Unicode代码点指定,而不适用于字节。
Unicode代码点U+FEFF ZERO WIDTH NO-BREAK SPACE
的数值(即官方标识,而非U+FEFF BYTE ORDER MARK
,但也用作BOM )是0xFEFF
(65279)。
以UTF-8编码的代码点值产生三个8位代码单元值0xEF 0xBB 0xBF
,这些值不受任何字节序问题的影响,这就是为什么UTF-8没有单独的LE和BE变体。
以UTF-16编码的相同代码点值产生一个16位代码单元值0xFEFF
。因为它是一个多字节(16位)值,所以当被解释为两个8位字节时它将受到字节序的影响,因此LE(0xFF 0xFE
)和BE(0xFE 0xFF
)变体。< / p>
不仅仅是受影响的BOM。 UTF-16字符串中的所有代码单元都受端序影响。 BOM帮助解码器知道用于整个字符串中的代码单元的字节序。
UTF-32也使用多字节(32位)代码单元,也受端序影响,因此它还具有LE和BE变体,以及32位BOM表示该字节序到解码器({ LE为{1}},BE为0xFF 0xFE 0x00 0x00
。是的,正如您可能猜到的那样,如果您事先不知道您正在处理哪种UTF,那么UTF-16LE BOM和UTF-32LE BOM之间存在歧义。 BOM用于标识字节序,因此名称为&#34; 字节顺序标记&#34;,而不是特定的编码(尽管它通常用于此目的)。
答案 1 :(得分:2)
为什么BOM是UTF-16(BE)的U + FE FF
不是。 BOM是字符编号U + FEFF。没有空格,它只是一个十六进制数,也就是65279.这个定义不依赖于用什么字节序列来表示任何特定编码中的字符。
在UTF-16LE,0xFE, 0xFF
中编码字符(*)的字节序列的十六进制表示与字符编号U+FEFF
的十六进制表示具有相同的数字顺序。这只是一个大端的人工制品,它把最重要的内容放在左边,就像人类对大六进制数一样。
(*实际上是基本多语言平面中的任何一个字符。当你超过这个范围时会变得更加毛发,因为它们不再适合两个字节。)