在UTF-16中,UTF-16BE,UTF-16LE,UTF-16的端点是计算机的字节序吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在UTF-16中,UTF-16BE,UTF-16LE,UTF-16的端点是计算机的字节序吗?相关的知识,希望对你有一定的参考价值。
UTF-16是一个双字节字符编码。交换两个字节的地址将产生UTF-16BE和UTF-16LE。
但我发现Ubuntu gedit
文本编辑器中存在名称UTF-16编码,以及UTF-16BE和UTF-16LE。使用C测试程序,我发现我的计算机是小端,并且UTF-16被确认为UTF-16LE的相同编码。
另外:在小/大端计算机中有两个字节顺序的值(例如整数)。小端计算机将在硬件中产生很少的端序值(除了Java生成的值,它总是形成一个大端)。
虽然文本可以在我的小端计算机中保存为UTF-16LE和UTF-16BE,但字符是一个字节一个字节生成的(例如ASCII字符串,对[3]的引用和刚刚定义的UTF-16的字节顺序)由人类 - 而不是大端机器写大端UTF-16而小端机器写小端UTF-16的现象的结果?
“UTF-16的结尾是计算机的字节序吗?”
可以从作者或文件读者的角度来看待计算机字节序的影响。
如果您正在以标准格式读取文件,那么读取它的机器应该无关紧要。格式应该足够明确,无论读取机器的字节顺序是什么,数据仍然可以正确读取。
这并不意味着格式不灵活。对于“UTF-16”(当格式名称中未使用“BE”或“LE”消歧时),该定义允许将文件标记为大端或小端。这是通过文件的前两个字节中的“字节顺序标记”(BOM)来完成的:
https://en.wikipedia.org/wiki/Byte_order_mark
BOM的存在为文件的编写者提供了选项。他们可能会选择为内存中的缓冲区写出最自然的字节序,并包含匹配的BOM。对于其他读者来说,这不一定是最有效的格式。但任何声称支持UTF-16的程序都应该能够以任何一种方式处理它。
所以是的 - 计算机的字节序可能会影响BOM标记的UTF-16文件的字节序选择。仍然...一个小端程序完全能够保存文件,标记为“UTF-16”并让它成为大端。只要BOM与数据一致,无论哪种机器写入或读取它都无关紧要。
......如果没有BOM怎么办?
这是事情变得有点朦胧的地方。
一方面,Unicode RFC 2781和Unicode FAQ很清楚。他们说,“UTF-16”格式的文件既不是0xFF 0xFE
也不是0xFE 0xFF
,而是interpreted as big endian:
默认情况下,未标记的表单使用大端字节序列化,但可能在开头包含一个字节顺序标记,以指示使用的实际字节序列化。
但是要知道你是否有没有BOM的UTF-16-LE,UTF-16-BE或UTF-16文件...你需要文件外的元数据告诉你它们中的哪一个。因为并不总是放置数据的地方,所以一些程序使用启发式算法。
考虑像this from Raymond Chen (2007)这样的东西:
您可能会认为生成没有BOM的UTF-16文件的程序已损坏,但这并不意味着它们不存在。例如,
cmd /u /c dir >results.txt
这会生成一个没有BOM的UTF-16LE文件。
这是一个有效的UTF-16LE文件,但存储“UTF-16LE”元标签的位置在哪里?只要将其称为UTF-16文件,有人通过这种情况的几率是多少?
根据经验,这个词有警告。维基百科page for UTF-16说:
如果BOM丢失,RFC 2781表示应该假设大端编码。 (实际上,由于Windows默认使用little-endian顺序,许多应用程序默认使用little-endian编码。)
“UTF-16”和“UTF-32”编码名称不精确:根据上下文,格式或协议,它表示带有BOM标记的UTF-16和UTF-32,或主机端的UTF-16和UTF-32没有BOM。在Windows上,“UTF-16”通常表示UTF-16-LE。
而且,Byte-Order-Mark Wikipedia article说:
Unicode标准的一致性条款D98(第3.10节)规定,“UTF-16编码方案可能也可能不以BOM开头。但是,当没有BOM时,如果没有更高级别的协议, UTF-16编码方案的字节顺序是big-endian。“
是否有更高级别的协议生效是可以解释的。例如,本机字节排序为little-endian的计算机本地文件可能被认为是隐式编码为UTF-16LE。因此,大端的推定被广泛忽视。
另一方面,当在因特网上可以访问这些相同的文件时,不能做出这样的推定。在ASCII范围内搜索16位字符或仅搜索空格字符(U + 0020)是一种确定UTF-16字节顺序的方法。
因此,尽管标准没有歧义,但背景在实践中可能很重要。
正如@rici指出的那样,该标准已经存在了一段时间。不过,对声称为“UTF-16”的文件进行双重检查可能需要付费。或者甚至考虑你是否想要避免很多这些问题并接受UTF-8 ......
"Should UTF-16 be considered harmful?"
不,你不是看到小端计算机一直接收来自互联网的数据包,这是大端吗?
编码取决于您对内存的写入方式,而不是您的体系结构的方式。
Unicode编码方案在Unicode standard的3.10节中定义。该标准定义了七种编码方案:
- 8位:UTF-8
- 16位:UTF-16BE,UTF-16LE和UTF-16
- 32位:UTF-32BE,UTF-32LE和UTF-32
在16位和32位编码的情况下,这三种变体的字节顺序不同,可以是显式的,也可以通过用Byte Order Mark(BOM)字符U + FEFF开始字符串来表示:
LE
变种绝对是小端的;首先编码低位字节。不允许BOM,因此初始字符U + FEFF是零宽度不间断空间。BE
变种绝对是大端的;首先编码高位字节。与LE
变体一样,不允许BOM,因此初始字符U + FEFF是零宽度不间断空间。- 没有endian标记的变体可能是big-little-endian。通常它将以定义字节序的BOM开始。如果没有BOM,则假定为big-endian编码。
如果要使用16位或32位编码方案进行数据序列化,通常建议使用带有显式BOM的未标记变体。但是,UTF-8是一种更常见的数据交换格式。
虽然UTF-8不需要字节序标记,但允许(但不推荐)使用BOM启动UTF-8编码字符串;这可以用于区分Unicode编码方案。许多Windows程序都这样做,并且在UTF-8传输开始时的U + FEFF应该被视为BOM(因此不是Unicode数据)。
以上是关于在UTF-16中,UTF-16BE,UTF-16LE,UTF-16的端点是计算机的字节序吗?的主要内容,如果未能解决你的问题,请参考以下文章