UTF-8和UTF-16的由来

Unicode第一个版本涉及到两个步骤:首先定义一个规范,给所有的字符指定一个唯一对应的数字,Unicode是用0至65535(2的16次方)之间的数字来表示所有字符,其中0至127这128个数字表示的字符仍然跟ASCII完全一样;第二怎么把字符对应的数字(0至65535)转化成01串保保存在计算机中。在保存时就涉及到了在计算机中占多少字节空间,就有不同的保存方式,于是出现了UTF(unicode transformation format):UTF-8和UTF-16。

UTF-8 & UTF-16

  1. UTF-16表示”汉”:比较简单,就是01101100 01001001(共16 bit,两个字节),程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析。
  2. UTF-8表示”汉”:比较复杂,因为程序是一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把一个、两个或三个字节做为一个单元来处理。规则如下:
    • 0xxxxxxx:如果是这样的格式,也就是以0开头就表示把一个字节做为一个单元,就跟ASCII完全一样;
    • 110xxxxx 10xxxxxx:如果是这样的格式,则把两个字节当一个单元,可表示2的11次方2048个字符;
    • 1110xxxx 10xxxxxx 10xxxxxx:如果是这样的格式,则把三个字节当一个单元,可表示2的16次方,65536个字符。
  3. 由于UTF-16不需要用其它字符来做标志,所以两字节也就是2的16次能表示65536个字符;
  4. 而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符,而三个字节能表示2的16次方,65536个字符。
  5. 由于”汉”的编码27721大于2048了所有两个字节还不够,所以用1110xxxx 10xxxxxx 10xxxxxx这种格式,把27721对应的二进制从左到右填充XXX符号(实际上不一定从左到右,也可以从右到左)。
  6. 由于填充方式的不一样,于是就出现了Big-Endian、Little-Endian的术语。Big-Endian就是从左到右,Little-Endian是从右到左。

     //如果把UTF-16的byte字节流强转为UTF-8的字符串,对于ASCII字符,会被拆分为2个,一个是ASCII字符,另一个是空字符
     string result = Encoding.UTF8.GetString(utf16Bytes);
    

ASCII

  • 176: °, Alt+176