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

Unicode 为什么添加两个字节的UTF-8编码不';不能给出字符的代码点吗?,unicode,encoding,utf-8,Unicode,Encoding,Utf 8,首先,我对UTF-8编码方案的理解可能是错误的,因为我刚刚开始使用unicode。我遇到的一个有趣的例子是: 但是,Unicode字符有一种与ASCII兼容的编码方案。它被称为UTF-8。在UTF-8下,0到127之间的字符数的字节编码是单个字节的二进制值,就像ASCII一样。但是,对于128到65535之间的字符数,将使用多个字节。如果第一个字节的值介于128和255之间,则会将其解释为指示后面的字节数。后面的字节编码单个字符数。字符编码中后面的所有字节的值也在128和255之间,因此0和12

首先,我对UTF-8编码方案的理解可能是错误的,因为我刚刚开始使用unicode。我遇到的一个有趣的例子是:

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

例如,在拉丁语1和Unicode中字符号均为233的字符é在传统拉丁语1编码中由值为233的单个字节表示,但在UTF-8中由值为195和169的两个字节表示

在我的理解和理解中,因为字符é在unicode(233)中的值大于128,所以它由两个字节表示。这两个字节的值介于128和255之间,为了区分只需要一个字节的ASCII字符,技术上使用7位。但是,我们如何使用存储在两个字节中的值195和169来达到数字233呢?或者从两个字节中获取233的过程是什么?显然,如果我们将两个值(两个字节)相加,我们会得到195+169=364,这与字符的代码点不同,233。我错过了什么


*我完全理解有些字符需要更多的字节来表示,但那是另一回事。

UTF-8是一种编码方案。仅仅将原始字节添加在一起是不够的,您必须先删除编码部分,然后将剩余的位合并(而不是添加)在一起

UTF-8在中正式定义,定义如下表:

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
1
s和
0
s是文字,它们必须显示在编码字节中。
x
s表示正在编码的码点的原始位

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

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

代码点
U+00E9
0x000000E9
作为一个十六进制的32位数字。即以二进制位表示的
00000000000000000001101001
。该表的第二行仅使用代码点的11位,因此您可以去掉高21位,并用剩余的11个低位填充
x
s:

   11000000 10000000
OR    00011   101001
--------------------
   11000011 10101001 = 0xC3 0xA9
要反转此过程,只需从每个字节中删除非
x
位,并将其余位连接在一起:

    11000011 10101001
AND 00011111 00111111
---------------------
       00011   101001 = 11101001 = 0xE9

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

在Wikipedia上查找UTF8。描述了算法。您需要应用中学数学中的位置值概念,或者,在位运算中,移位或乘法。如果你读C,有很多的实现。我看了这个视频,它真的很有帮助:这里也很好地解释了算法:知道算法是如何工作的就足够了。我不打算实施它或任何事情。
    11000011 10101001
AND 00011111 00111111
---------------------
       00011   101001 = 11101001 = 0xE9