为什么 Unicode 有大端或小端,而 UTF-8 没有?

Tii*_*ina 5 unicode character-encoding utf-8 endian

UNICODE 对一个字符使用 2 个字节,因此它有或大或小的 endian 差异。例如,字符 ? 是54 C8十六进制的。因此它的 UTF-8 是:

11100101 10010011 10001000
Run Code Online (Sandbox Code Playgroud)

UTF-8 使用 3 个字节来表示相同的字符,但它没有大端或小端。为什么?

use*_*686 35

注意:由于历史原因,Windows 对 UCS-2 使用术语“Unicode”——最初这是将Unicode 代码点编码为字节的唯一方法,因此区别并不重要。但在现代术语中,这两个例子都是 Unicode,但第一个具体是 UCS-2 或 UTF-16,第二个是 UTF-8。

UCS-2 有 big-endian 和 little-endian,因为它直接将代码点表示为 16 位“uint16_t”或“short int”数字,就像在 C 和其他编程语言中一样。它与其说是“编码”,不如说是数值的直接内存表示,并且因为 uint16_t 在不同机器上可以是 BE 或 LE,UCS-2 也是如此。后来的 UTF-16 只是为了兼容性继承了同样的烂摊子。

(它可能被用于特定字节序定义,但我想他们认为这是超出范围或不得不之间代表着不同的硬件厂商或某事的人,我不知道实际的历史。妥协。)

同时,UTF-8 是一种可变长度编码,它可以使用 1 到 6 个字节的任意位置来表示 31 位值。字节表示与 CPU 架构完全没有关系;相反,有一种特定的算法可以将数字编码为字节,反之亦然。无论它在什么 CPU 上运行,该算法总是以相同的顺序输出或消耗位。

  • 你好呀。一些注意事项:**1)** Windows 世界中的“Unicode”特别是 UTF-16 _Little Endian_,因为它们还有一个“BigEndianUnicode”,即 UTF-16 BE。**2)** UTF-16 也是可变长度的,因为补充字符由两个 UTF-16 代码单元的代理对组成。和 **3)** 出于所有实际目的,UTF-8 最多使用 4 个字节,因为 Unicode 标准明确指出,仅对 Unicode 定义的 1,114,111 个最大代码点(即 UTF- 16 限制)。 (18认同)
  • UTF-16 *是*一种编码。它不是编码成字节,而是 16 位字。将这些单词编码为字节是字节序发挥作用的地方。 (14认同)
  • @Solomon Windows 中的“Unicode”在大多数情况下是指 UCS2 而不是 UTF-16(我认为有些较新的 API 符合 UTF-16,但绝大多数不是)。当谈论关于 Unicode 的各种或固定长度编码时,人们通常指的是 unicode *codepoints* 而不是字形。最大尺寸会更长。(实际上,人们应该关心字形而不是代码点,尽管我同意这使得 UTF-16 是固定长度这一事实无关紧要) (3认同)
  • 请注意,在最近的 Windows 10 版本(准确地说是 1903 年)中,如果正确设置进程代码页,“ASCII”Win32 API 也接受有效的 UTF-8:https://docs.microsoft.com/en-us/windows /uwp/design/globalizing/use-utf8-code-page#set-a-process-code-page-to-utf-8。 (2认同)
  • @Voo Windows 中的“Unicode”_is_ UTF-16 LE。**A)**“另存为...”对话框,选择“使用编码保存”,提供 _Unicode (CP 1200)_ 和 _Unicode (Big-Endian ; CP 1201)_(请参阅 https://docs.microsoft .com/en-us/windows/win32/intl/code-page-identifiers)。**B)** 自 1996 年的 Unicode 2.0 以来,UCS-2 就不再是 _encoding_;它只是表示一个过程没有将代理对解释为它们的补充代码点。请参阅 https://www.unicode.org/faq/utf_bom.html#utf16-11 和 http://www.unicode.org/versions/Unicode13.0.0/appC.pdf#G1823(C.2 编码形式部分) ISO/IEC 10646 第 11 页)。 (2认同)

phu*_*clv 22

与为什么字节数组(char[]在 C 或byte[]许多其他语言中)没有任何关联的字节序但其他类型的数组比byte它大的原因完全相同。这是因为字节序将多个字节表示的值存储到 memory 的方式。如果您只有一个字节,那么您只有一种方法将其存储到内存中。但是如果 anint由索引为 1 到 4 的 4 个字节组成,那么您可以以多种不同的顺序存储它,例如 [1, 2, 3, 4], [4, 3, 2, 1], [2, 1, 4, 3], [3, 1, 2, 4]...这是小端,大端,混合端...

Unicode 有许多不同的编码,称为Unicode 转换格式,主要的有 UTF-8、UTF-16 和 UTF-32。UTF-16 和 UTF-32分别以 16 位和 32 位单位工作,很明显,当您将 2 或 4 个字节存储到字节寻址内存中时,您必须定义要读取/写入的字节顺序。UTF-8 OTOH 以字节为单位工作,因此它没有字节序

  • 从技术上讲,UTF-8 适用于 *octets*,而不是 *bytes*。一个字节只是最小的可单独寻址的内存单元。在许多流行的体系结构上,一个字节是 8 位,但这并不能保证。虽然 6 位、7 位、9 位、10 位、11 位和 12 位字节在这一点上主要是历史上的好奇心,但今天使用的*有*架构具有例如 16 位、 24 位和 32 位字节,以及具有可变大小字节的体系结构和根本没有字节的体系结构(或具有 1 位字节,但是您想查看它)。 (6认同)
  • 如果你在 9 位架构上实现 unicode,那么 https://datatracker.ietf.org/doc/html/rfc4042 可能是相关的,但实际上你可能只是假装你有 8 位字节和 UTF-8并忽略额外的位。 (2认同)