我不太了解UTF编码和BOM背后的原理。
如果计算机已经知道如何将多字节数据类型(例如,大小为4字节的整数)组合成一个变量,那么在UTF-16和UTF-32中使用BOM有什么意义呢?为什么我们需要为这些编码明确指定它呢?
为什么我们不需要为UTF-8指定它? Unicode标准表示它是“面向字节的”,但即便如此,我们还需要知道它是否是编码代码点的第一个字节。或者它是否在每个字符的前/后位中指定?
答案 0 :(得分:2)
UTF-16是两个字节宽,让我们调用字节B0|B1
。
假设我们有字母'a',这在逻辑上是0x0061。不幸的是,不同的计算机体系结构以不同的方式将这个数字存储在内存中,在x86平台上,首先存储较低有效字节(在较低的内存地址处),因此'a'将存储为00|61
。在PowerPC上,它将存储为61|00
,因此这两种架构称为小端和大端。
为了加速字符串处理库,通常以本机顺序存储两个字节字符(大结尾或小结尾)。交换字节太贵了。
现在假设PowerPC上的某个人将字符串写入文件,库将写入字节00|61
,现在x86上的某些人想要读取这些字节,但这是否意味着00|61
或{{1} }?我们可以在字符串的开头放置特殊序列,这样任何人都会知道用于保存字符串的字节顺序,并正确处理它(在字节序之间转换字符串是一项代价高昂的操作,但大多数情况下x86字符串将在x86 arch上读取,和PowerPC机器上的PowerPC字符串)
使用UTF-8这是不同的故事,UTF-8使用单一顺序并将字符长度编码为第一个字符的第一位模式。 UTF-8编码在Wikipedia上有详细描述。一般来说,它是设计以避免endian'ess的问题
答案 1 :(得分:1)
不同的架构可以对事物进行不同的编码。一个系统可能将0x12345678写为0x12 0x34 0x56 0x78,另一个系统可能将其写为0x78 0x56 0x34 0x12。了解源系统如何编写内容非常重要。字节是读取或写入的最小单位,因此如果格式是逐字节写入的,则没有问题,就像没有系统在读取另一个写入的ASCII文件时一样。
UTF-16 BOM,U+FEFF
将写为0xFE 0xFF或0xFF 0xFE,具体取决于系统。知道这些字节的写入顺序告诉读者字节将用于文件其余部分的顺序。 UTF-32使用相同的BOM字符,填充16个零位,但其使用方法相同。
答案 2 :(得分:1)
UTF-16和UTF-32编码不指定字节顺序。在8位字节流中,代码点U + FEFF可以用UTF-16编码为字节FE,FF(大端)或FF,FE(小端)。流编写器显然无法知道流将在哪里结束(文件,网络套接字,本地程序?),因此您在开头放置BOM以帮助读者确定编码和字节顺序变体。 / p>
UTF-8没有这种歧义,因为它从一开始就是面向字节的编码。在UTF-8中编码此代码点的唯一方法是以精确的顺序使用字节EF,BB,BF。 (方便的是,序列化的第一个字节中的高位也会显示序列占用的字节数。)