为什么添加UTF-8编码的两个字节不能给出字符的代码点?

dir*_*obs 0 unicode encoding utf-8

首先,我对UTF-8编码方案如何工作的理解可能是错的,因为我刚刚开始使用unicode.我遇到的一个有趣的网页说:

但是,有一种与ASCII兼容的Unicode字符编码方案.它被称为UTF-8.在UTF-8下,0到127之间字符编号的字节编码是单字节的二进制值,就像ASCII一样.但是,对于128到65535之间的字符数,使用多个字节.如果第一个字节的值介于128和255之间,则会将其解释为指示要遵循的字节数.后面的字节编码单个字符编号.字符编码中的所有字节也具有128到255之间的值,因此在0到127之间的单字节字符和作为多字节字符表示的一部分的字节之间永远不会有任何混淆.

例如,拉丁语1和Unicode中字符编号为233的字符é由传统Latin 1编码中的值为233的单个字节表示,但表示为两个字节,其值为195和169(以UTF为单位) -8.

在我的解释和理解中,因为字符é在unicode(233)中的值大于128,所以它由两个字节表示.这两个字节的值介于128和255之间,以区分仅需要一个字节的ASCII字符,技术上使用7位.乙UT斯达康如何才能达到使用存储在两个字节的值195和169的数量233?或者从两个字节中获取233的过程是什么?显然,如果我们添加两个值(两个字节),我们得到195 + 169 = 364 ,这与字符é,233 的代码点不同.我在这里缺少什么?

*我完全理解一些字符需要更多字节来表示,但这是另一个故事.

Rem*_*eau 7

UTF-8是一种编码方案.仅将原始字节添加到一起是不够的,您必须首先删除编码部分,然后将剩余的位连接(不添加).

UTF-8在RFC 3629中正式定义,它定义了下表:

Char. number range  |        UTF-8 octet sequence
   (hexadecimal)    |              (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

这在维基百科上更好地可视化:

UTF-8编码

现在,让我们将它应用于您的示例Unicode字符é,即Unicode代码点U+00E9 SMALL LETTER E WITH ACUTE.

如果查看表,则codepoint U+00E9属于第2行,因此使用两个字节进行编码:

110xxxxx 10xxxxxx
Run Code Online (Sandbox Code Playgroud)

1S和0s为文字,如图中编码的字节它们必须出现.的xs为正被编码的码点的原始比特.

设置最高位以1确保字节不会与7位ASCII字符混淆.1编码序列的第一个字节中的s 数也用于指定完整序列中的总字节数.

完整的Unicode指令表需要最多21位来表示所有可能的代码点(包括U+10FFFF,这是UTF-16可以物理编码的最高代码点.UTF-8可以物理编码更高的代码点,但受RFC的人为限制与UTF-16保持100%的兼容性.由于大多数编程语言中没有21位数据类型,因此下一个最高数据类型是32位整数.

Codepoint U+00E90x000000E9一个32位的十六进制数字.那是00000000 0000000 00000000 11101001二进制位.表的第2行仅使用代码点的11位,因此您将剥离高21位并x用剩余的11个低位填充s:

   11000000 10000000
OR    00011   101001
--------------------
   11000011 10101001 = 0xC3 0xA9
Run Code Online (Sandbox Code Playgroud)

要反转该过程,只需x从每个字节中删除非位,并将其余位加在一起:

    11000011 10101001
AND 00011111 00111111
---------------------
       00011   101001 = 11101001 = 0xE9
Run Code Online (Sandbox Code Playgroud)

如果您需要在特定编程语言中实现此算法的帮助,那么有大量示例和教程可以从编码角度展示算法.