encoding.utf8.getstring怎么得出正确字符的

utf8编码不是固定字节,有的是1个字节有的是2个字节有的是3个,那么


encoding.utf8.getstring是怎么把一堆字节解析成正确的字符,比如说有6个字节,为什么不会判断成6个单字节或者1+2+3,或者3+3或者2+2+2呢?

其实是utf8编码

0xxxxxxx                                                                                  (00-7f)
110xxxxx 10xxxxxx                                                                  (c0-df)(80-bf)
1110xxxx 10xxxxxx 10xxxxxx                                                  (e0-ef)(80-bf)(80-bf)
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx                                  (f0-f7)(80-bf)(80-bf)(80-bf)
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx                  (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf)
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf)

如果第一个字节二进制是110就说明2个字节,1110就说明3个字节类推,而且其他字节二进制开头都用10来表示,而如果是0-127那么就是单字节,这样的格式就可以不会混淆了


比如6个字节

11001111   10000000   11100101   10010101   10001010   01000001  

110说明2字节 11001111   10000000是一个字符,第二个也是10开头

接下来1110说明是3个11100101   10010101   10001010,后两个也是10开头

最后0开头说明就1个

那么这个字节数组转字符串也就是“π啊A”


如果破坏了这个规则,c#会按照顺序,不会后面全变乱码,比如把第一个改成11101111,把第三个改成01100001

11101111   10000000   01100001   10010101   10001010   01000001  

那么上来第一个1110看起来3个,第二个10开头对了,但第3个就不符合10开头了,所以把第一第二个先来乱码一个?

那么从第三个开始,发现0开头单字节对了,于是显示a

接下来第四个上来10开头也不对,乱码一个?

第五个也是上来10开头,乱码一个?

直到第六个0开头,单字节,就对了,显示A

这样结果就是"?a??A"

这样的好处就是不会因为一大篇文章中坏了一点就导致整篇文章全都乱码。



你可能感兴趣的:(C#)