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

时间:2017-06-15 11:03:03

标签: unicode encoding utf-8 character-encoding

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

3 个答案:

答案 0 :(得分:22)

  

例如,“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的单字节值与多字节序列中使用的单字节值不重叠。字节0x000x7F仅用于ASCII而不用于其他内容; 0x7F之上的字节仅用于多字节序列而不用于其他任何内容。此外,在多字节序列开头使用的字节也不能出现在那些序列的任何其他位置。

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

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

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

例如:U + 0754介于U + 0080和U + 07FF之间,因此它需要两个字节。二进制文件中的0x075411101010100,因此您将x替换为这些数字:

110 11101 10 010100

答案 1 :(得分:13)

简答:

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

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

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

  

0 1000001 110 11101 10 010100

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

请参阅here UTF-8如何编码Unicode代码点。

答案 2 :(得分:1)

请澄清一下,ASCII是指标准的7位ASCII,而不是欧洲常用的扩展的8位ASCII。

因此,第一个字节(0x80至0xFFFF)的一部分变为双字节表示,而两个字节(0x0800至0xFFFF)的第二个字节的一部分变为完整的三字节表示。

四字节表示仅使用最低的三个字节,并且仅使用‭16.777.215‬可用可能性中的1.114.111

您有一个xls here

这意味着解释器在找到那些二进制模式时必须“跳回”一个NUL(0)字节。

希望这对某人有帮助!