hao*_*hou 5 c unicode utf-16 endianness
UTF-16是一个双字节字符编码.交换两个字节的地址将产生UTF-16BE和UTF-16LE.
但我发现命名的UTF-16编码存在于Ubuntu"gedit"文本编辑器中,以及UTF-16BE和UTF-16LE.使用C测试程序,我发现我的计算机是小端,并且UTF-16被确认为UTF-16LE的相同编码.
另外:在小/大端计算机中有两个字节顺序的值(例如整数).小端计算机将在硬件中产生很少的字节序值(除了Java生成的值,它总是形成一个大端).
虽然文本可以在我的小端计算机中保存为UTF-16LE和UTF-16BE,但字符是一个字节一个字节生成的(例如ASCII字符串,对[3]的引用和刚刚定义的UTF-16的字节顺序)由人类 - 不是因为大端机器写大端UTF-16而小端机写小端UTF-16的现象?
[1] http://www.ibm.com/developerworks/aix/library/au-endianc/
[2] http://teaching.idallen.com/cst8281/10w/notes/110_byte_order_endian.html
[3] ASCII字符串和字节序
[4] 字节顺序只影响数字的内存布局,而不影响字符串吗?这是一个字符串和机器的字节顺序之间的关系.
"UTF-16的结尾是计算机的字节序吗?"
可以从作者或文件读者的角度来看待计算机字节序的影响.
如果您正在以标准格式读取文件,那么读取它的机器应该无关紧要.格式应该足够明确,无论读取机器的字节顺序是什么,数据仍然可以正确读取.
这并不意味着格式不灵活.随着"UTF-16"(当一个"是"或"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是被解释为大端:
默认情况下,未标记的表单使用大端字节序列化,但可能在开头包含一个字节顺序标记,以指示使用的实际字节序列化.
但是要知道你是否有没有BOM的UTF-16-LE,UTF-16-BE或UTF-16文件...你需要文件外的元数据告诉你它们中的哪一个.因为并不总是放置数据的地方,所以一些程序使用启发式算法.
从Raymond Chen(2007)那里考虑这样的事情:
您可能会认为生成没有BOM的UTF-16文件的程序已损坏,但这并不意味着它们不存在.例如,
Run Code Online (Sandbox Code Playgroud)cmd /u /c dir >results.txt这会生成一个没有BOM的UTF-16LE文件.
这是一个有效的UTF-16LE文件,但存储"UTF-16LE"元标签的位置在哪里?只要将其称为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文章说:
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 ......
Unicode 编码方案在Unicode 标准第 3.10 节中定义。该标准定义了七种编码方案:
在 16 位和 32 位编码的情况下,这三个变体的字节顺序不同,字节顺序可以是明确的,也可以通过以字节顺序标记(BOM) 字符 U+FEFF 开始字符串来指示:
LE变体绝对是小端字节序;首先对低位字节进行编码。不允许使用 BOM,因此初始字符 U+FEFF 是零宽度不间断空格。BE变体绝对是大端字节序;首先对高位字节进行编码。与LE变体一样,不允许使用 BOM,因此初始字符 U+FEFF 是零宽度不间断空格。如果要使用 16 位或 32 位编码方案进行数据序列化,通常建议使用具有显式 BOM 的未标记变体。然而,UTF-8 是一种更常见的数据交换格式。
尽管 UTF-8 不需要字节序标记,但允许(但不推荐)以 BOM 开头 UTF-8 编码字符串;这可用于区分 Unicode 编码方案。许多 Windows 程序都会这样做,并且 UTF-8 传输开头的 U+FEFF 可能应该被视为 BOM(因此不被视为 Unicode 数据)。