UTF-8编码如何识别单字节和双字节字符?

Gan*_*S R 17 unicode encoding utf-8 character-encoding

最近我遇到了一个关于字符编码的问题,而我正在深入研究字符集和字符编码这个疑问在我脑海中浮现.由于其向后兼容ASCII,因此最受欢迎的是UTF-8编码.因为UTF-8是可变长度的编码格式,它如何区分单字节和双字节字符.例如,"Aݔ"存储为"410754"(A的Unicode为41,阿拉伯字符的Unicode为0754.How编码标识41是一个字符,0754是另一个字符双字节字符?为什么不将4107视为一个双字节字符而将54视为单字节字符?

Cha*_*uff 29

例如,"Aݔ"存储为"410754"

这不是UTF-8的工作原理.

字符U + 0000到U + 007F(也称为ASCII)存储为单个字节.它们是唯一的字符,其代码点在数字上与其UTF-8表示相匹配.例如,U + 0041变为0x41其是0100001二进制.

所有其他字符用多个字节表示.U + 0080到U + 07FF各使用两个字节,U + 0800到U + FFFF各使用三个字节,而U + 10000到U + 10FFFF各使用四个字节.

计算机知道一个字符结束的位置和下一个字符的开始,因为UTF-8的设计使得用于ASCII的单字节值与多字节序列中使用的单字节值不重叠.字节0x00直通0x7F仅用于ASCII而不是其他内容; 上面的字节0x7F仅用于多字节序列而不用于其他任何内容.此外,在多字节序列的开头使用的字节也不能出现在那些序列中的任何其他位置.

因此,需要对代码点进行编码.考虑以下二进制模式:

  • 2个字节: 110xxxxx 10xxxxxx
  • 3个字节: 1110xxxx 10xxxxxx 10xxxxxx
  • 4字节: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

第一个字节中的1个数量告诉您有多少后续字节仍然属于同一个字符.属于序列的所有字节都以10二进制开头.要对字符进行编码,请将其代码点转换为二进制并填写x.

例如:U + 0754介于U + 0080和U + 07FF之间,因此它需要两个字节.0x0754在二进制文件中11101010100,所以用这些数字替换x:

110 11101 10 010100

  • 另外两种Unicode格式是UTF-16和UTF-32.UTF-32使用四个字节的单位,这对于所有可能的Unicode值都足够了,因此所有代码点都可以不加修改地保存.U + 0754变为00 00 07 54.UTF-16使用两个字节的单位,对于U + FFFF的所有字符都足够,因此U + 0754变为07 54.超出FFFF的所有内容都被编码为两个所谓的代理,这是任何字符都不使用的特殊双字节代码点.同样,用于启动代理和结束代理的代码点不重叠. (2认同)

wei*_*eld 17

简短回答:

UTF-8旨在能够明确地识别文本流中每个字节类型:

  • 1字节代码(全部且仅ASCII字符)以0开头
  • 2字节代码的前导字节以两个1开始,后跟一个0(即110)
  • 3字节代码的前导字节以三个1开始,后跟一个0(即1110)
  • 4字节代码的前导字节以四个1开始,后跟一个0(即11110)
  • 连续字节(所有多字节代码)以单个1开始,后跟0(即10)

您的示例A?由Unicode代码点U + 0041和U + 0754组成,以UTF-8编码为:

0 1000001 110 11101 10 010100

因此,当解码时,UTF-8知道第一个字节必须是1字节代码,第二个字节必须是2字节代码的前导字节,第三个字节必须是连续字节,并且因为第二个字节是2字节代码的前导字节,第二个和第三个字节必须组成这个2字节代码.


请参阅此处 UTF-8如何编码Unicode代码点.