在UTF-8
编码中,一个字符可能由一个或多个字节组成。每个字节的前几位用于指示该字符需要多少字节来表示。具体来说,UTF-8
编码使用以下规则:
如果一个字节的最高位是0
,那么它表示一个ASCII
字符,并且该字节就是该字符的完整表示。
如果一个字节以110
开头,它表示这是一个两字节字符的第一个字节。
如果一个字节以1110
开头,它表示这是一个三字节字符的第一个字节。
如果一个字节以11110
开头,它表示这是一个四字节字符的第一个字节。
在你提供的byte[] bb
数组中:
csharp
byte[] bb = { 228, 189, 160, 229, 165, 189 };
228
(二进制表示为11100100
)是以1110
开头的,所以它表示一个三字节字符 的第一个字节。
229
(二进制表示为11100101
)同样是以1110
开头的,也表示一个三字节字符 的第一个字节。
在你的数组中,228
和229
都是各自三字节UTF-8
字符序列的开始。每个这样的序列都包含三个字节
其中第一个字节表示字符需要多少字节,而后面的字节包含字符的实际编码。
故要正确解码这些字节序列,你需要以三个字节为一组来解读它们。例如:
228, 189, 160
这三个字节一起表示一个UTF-8编码的字符。
229, 165, 189
这三个字节一起表示另一个UTF-8编码的字符。
当你使用Encoding.UTF8.GetString(bb)
时,.NET Framework
的UTF-8解码器
会识别这些字节序列,并将它们转换回对应的Unicode
字符,然后这些字符会被组合成一个字符串。
在你的例子中,228, 189, 160
对应的Unicode
字符是中
,而229, 165, 189
对应的Unicode
字符是文
。所以,当你显示这个字符串时,你会看到"中文
"。
简而言之,228
和229
在UTF-8
编码中的作用是标识三字节字符序列的开始。它们自身并不直接对应任何字符,而是与跟随它们的字节一起,共同表示一个特定的Unicode
字符。
注意:
csharp
1byte = 8bit