Unicode 为什么UTF-8字符串没有字节顺序问题?

Unicode 为什么UTF-8字符串没有字节顺序问题?,unicode,character-encoding,endianness,word,Unicode,Character Encoding,Endianness,Word,这个问题与我们有很大关系,但我将用一种完全不同的方式来表述,因为我无法编辑上面提到的问题 有一种说法是,在UTF-8编码的字符串中,BOM是冗余的,因为UTF-8是“面向字节的”,其中最小的代码单元是一个字节,并且您始终可以从字节的最高有效位判断它是单独表示字符还是仅表示字符的一部分。需要以UTF-8编码保存文件而不使用BOM,Jukka Korpela的“Unicode解释”还指出: 在UTF-8中,没有字节顺序问题,因为代码单元大小是一个八位字节。因此,使用BOM毫无用处 假设有一个仅由AS

这个问题与我们有很大关系,但我将用一种完全不同的方式来表述,因为我无法编辑上面提到的问题

有一种说法是,在UTF-8编码的字符串中,BOM是冗余的,因为UTF-8是“面向字节的”,其中最小的代码单元是一个字节,并且您始终可以从字节的最高有效位判断它是单独表示字符还是仅表示字符的一部分。需要以UTF-8编码保存文件而不使用BOM,Jukka Korpela的“Unicode解释”还指出:

在UTF-8中,没有字节顺序问题,因为代码单元大小是一个八位字节。因此,使用BOM毫无用处

假设有一个仅由ASCII字符组成的UTF-8字符串,比如“abcdefgh”。如果我将其存储在具有另一个endianness(使用32位字)的机器上,是否会将其更改为“dcbahgfe”,因为这里的一个字符是一个字节,并且它们的顺序在具有相反endianness的机器上颠倒(以相反的顺序存储)

如果情况并非如此,并且字节顺序在内存中总是相同的,而只在字中不同(在处理排序期间),那么为什么字节顺序对UTF-16编码很重要?也就是说,如果我知道编码是UTF-16,我地址是字节15,我就知道它是字符串中第8个代码单元的第一个字节,我需要得到第二个字节,以便找到由该代码单元表示的字符或代理项对的一部分

谁能告诉我哪里错了?我很确定,我对endianness和/或计算机硬件有一些误解,因此如果有人解释这一点或提供更多信息的链接,我将不胜感激


更新:

因此,如果有一个UTF-16字符串,比如abcdefgh,它可以以某种方式存储在内存中a0b0c0d0e0f0g0h00a0b0c0d0e0f0g0h(每交换两个字节,顺便说一下,我也不明白,为什么是两个而不是四个字节)。如果一个人在一台具有相反端点的机器上读取这个字符串,即使一次读取一个字节,他仍然需要交换字节

现在,如果有相同的UTF-8字符串abcdefgh,它以某种方式存储为字节序列。问题是在这种情况下为什么不交换字节?或者,如果是这样,为什么人们在阅读时不需要交换它们呢?因为,据我所知,对于这个级别的硬件和软件来说,编码之间没有区别,这只是一个字节序列。那么,UTF-16中的字节如何交换,而UTF-8中的字节如何不交换呢

我故意使用abcdefg,以表明即使使用这些简单的字符(编码需要一个字节)也可能存在问题(这不是真的,我知道我错了,但我不理解为什么)。另外,在UTF-8中,人们总是可以从寻找字节中最高有效位的其他字符中分辨出a、b、c等。也就是说,如果他正在寻址字节13(从1开始),并且它是0110001,那么肯定是a字符。现在还不知道在这个字符之前的字符串中有多少个字符,但很明显,这是a,而不是其他字符编码的一部分。现在假设我一次读取4个字节,它们的值是a,b,c,d。如何知道预期的顺序?

32位字->“dcbahgfe”:您可以这样查看,但大多数处理器可以访问八位字节的内存(术语是:内存是字节可寻址的)。所以,如果你有一个压缩的数据结构,它是一个字节序列,它们将有顺序地址

如果您读写单词并将它们视为更大的整数,那么您必须按特定顺序打包字节,但这不是尾数问题,而是该级别的算术问题



至于对齐,则取决于编译器和堆库。许多将在结构之间进行填充,以便每个结构都从一个有效的地址边界开始。

您必须认识到,处理UTF-8或UTF-16的机器的端点对于回答为什么UTF-8没有字节顺序问题并不重要。重要的是UTF-8和UTF-16是字节流。UTF-8基于8位代码单元,因此只有一种格式化字节流的方法:简单地将一个字节放在另一个字节之后。另一方面,UTF-16基于16位代码单元。有两种方法可以对字节流中的16位值进行编码:最高有效字节优先(big-endian)或最低有效字节优先(little-endian)。这就是为什么有两种类型的UTF-16字节流,通常称为UTF-16-BE和UTF-16-LE


在处理UTF-8时,实际计算机如何寻址、读取和写入内存是一个完全无关的问题。计算机可能会使用一种奇怪的寻址方案,使UTF-8处理复杂化,需要字节交换或其他方式。因此,可能存在与特定体系结构相关的字节顺序问题,但这些不是与UTF-8规范相关的字节顺序问题。实现可以确保UTF-8字节流的格式化方式只有一种。

每个处理器将第二个字节放在第一个字节之后。Endian ness只影响在多个字节上运行的内存读取。@HansPassant,你的意思是,使用UTF-8字符串时,应用程序总是一次读取一个字节。比如说,使用UTF-16,应用程序一次可以读取两个字节(可能会提高性能等),但也可以一次读取一个字节,在这种情况下,字节顺序也与UTF-16无关?是的。您可以一次读取一个字节的utf-16,但是如果endian不匹配,您仍然必须为每个编码元素交换两个字节。所以这并不能解决任何问题,读取两个字节更有效。@HansPassant,你能解释一下为什么我不交换UTF-8的字节吗