c#解码器如何知道一个字符应该使用的确切字节数?
本文关键字:字节数 字符 何知道 解码器 一个 | 更新日期: 2023-09-27 18:16:07
例如,一个流有四个字节: d800 DC 05。解码器(例如:System.Text.Decoder
)知道它应该把它们当作一个字符'uD800'udc05
或两个单独的字符'uD800
和'udc05
吗?谢谢。
您的问题实际上是关于UTF-16和代理对。
两个代码单元 U+D800和U+DC05总是表示代理对。这两个代码单元组合成一个代码点,即一个字符。
c#调用代码单元char
,这可能有点误导,因为它有时需要两个char
值(一对代理)来创建一个"字符",正如你所注意到的。
U+D800和U+DBFF之间的任何代码单元(char
)值总是表示代理对的下部分,而U+DC00和U+DFFF之间的任何代码单元是对应的上部分。
该域之外的代码单元,即U+0000到U+D7FF或U+E000到U+FFFF表示它们自己,因此在这些范围内,一个UTF-16代码单元对应一个Unicode码点。
编辑:问题改为询问UTF-8。
我将使用octet来表示正好8位的字(所以一个octet就是大多数人所说的字节)。
在UTF-8中,您可以从八位元组中第一个0位的位置看出该八位元组在UTF-8序列中的位置。
-
0xxxxxxx
:如果第一个位为0,则该八位组构成1-八位组序列(ASCII值) -
10xxxxxx
:如果八位元组从10
开始,这是一个延续八位元组,即不是序列 的起始。 -
110xxxxx
:这是2-octet序列中的初始字节 -
1110xxxx
:这是3-octet序列中的初始字节 -
11110xxx
:这是4-octet序列中的初始字节
由于现代UTF-8不允许5- 8字节或更长的序列,因此以5个1开头的八位字节是非法的,11111xxx
。但在早期版本中,上述方案将被扩展为允许5-八位字节和6-八位字节序列(有时也更长)。
当比较UTF-16和UTF-8时,请注意,在UTF-16中只需要一个16位代码单元的码点,与UTF-8中可以用1、2或3八位字节序列组成的码点完全对应。而在UTF-16中需要代理对的代码点(即两个UTF-16代码单元)与在UTF-8中需要4个八位字节序列的代码点完全对应。
有。net Framework源代码,可以看看。
System.Text.Decoder的源代码放在这里。所以你可以在这里找到你想知道的关于你的问题的所有信息。