在UTF-16中,UTF-16BE,UTF-16LE,UTF-16的端点是计算机的字节序吗?

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] 字节顺序只影响数字的内存布局,而不影响字符串吗?这是一个字符串和机器的字节顺序之间的关系.

Hos*_*ork 8

"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文件的程序已损坏,但这并不意味着它们不存在.例如,

cmd /u /c dir >results.txt
Run Code Online (Sandbox Code Playgroud)

这会生成一个没有BOM的UTF-16LE文件.

这是一个有效的UTF-16LE文件,但存储"UTF-16LE"元标签的位置在哪里?只要将其称为UTF-16文件,有人通过这种情况的几率是多少?

根据经验,这个词有警告.UTF-16的维基百科页面说:

如果BOM丢失,RFC 2781表示应该假设大端编码.(实际上,由于Windows默认使用little-endian顺序,许多应用程序默认使用little-endian编码.)

unicode.readthedocs.org说:

"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 ......

"UTF-16应该被视为有害吗?"

  • UTF-16 在 Unicode 标准(http://unicode.org)中进行了精确定义,恕我直言,该标准是有关 Unicode 的默认信息源。 (3认同)
  • @rici,如果常见做法与规范相反,那么忽略这一事实将是愚蠢的。我认为这个答案充分回避了这个问题。 (3认同)
  • @mark:当前标准允许使用 utf-8 格式的 BOM,这意味着如果实体以 U+FEFF 开头,则该字符将被忽略。Windows 符合;较新的 Unix 应用程序往往会遵循这些规定,但有些应用程序不会忽略 BOM。 (2认同)

ric*_*ici 5

Unicode 编码方案在Unicode 标准第 3.10 节中定义。该标准定义了七种编码方案:

  • 8 位:UTF-8
  • 16 位:UTF-16BE、UTF-16LE 和 UTF-16
  • 32 位:UTF-32BE、UTF-32LE 和 UTF-32

在 16 位和 32 位编码的情况下,这三个变体的字节顺序不同,字节顺序可以是明确的,也可以通过以字节顺序标记(BOM) 字符 U+FEFF 开始字符串来指示:

  • LE变体绝对是小端字节序;首先对低位字节进行编码。不允许使用 BOM,因此初始字符 U+FEFF 是零宽度不间断空格。
  • BE变体绝对是大端字节序;首先对高位字节进行编码。与LE变体一样,不允许使用 BOM,因此初始字符 U+FEFF 是零宽度不间断空格。
  • 没有字节序标记的变体可能是大字节序或小字节序。通常它会以定义字节序的 BOM 开头。如果没有 BOM,则假定采用大端编码。

如果要使用 16 位或 32 位编码方案进行数据序列化,通常建议使用具有显式 BOM 的未标记变体。然而,UTF-8 是一种更常见的数据交换格式。

尽管 UTF-8 不需要字节序标记,但允许(但不推荐)以 BOM 开头 UTF-8 编码字符串;这可用于区分 Unicode 编码方案。许多 Windows 程序都会这样做,并且 UTF-8 传输开头的 U+FEFF 可能应该被视为 BOM(因此不被视为 Unicode 数据)。


phu*_*clv 1

不,您没有看到小端计算机一直从互联网接收大端数据包吗?

编码取决于您写入内存的方式,而不是您的架构。