UTF-8编码的转换

一.UNICODE的相关概念

UNICODE是为了处理包括中文,日文等字符而提出的一种通用的字符集。最初的UNICODE为双字节字符集,即16位编码,能够包括65,536个字符。但这样的容量并不能满足所有需要,因此,现在的UNICODE已经扩展到4个字节,能够容纳1,112,064 个字符,而这些在16位之后的扩展背称为增补字符。

编码字符集是一个字符集,它为每一个字符分配一个唯一数字。Unicode 标准的核心是一个编码字符集,字母“A”的编码为 0041 和字符“?”的编码为 20AC。Unicode 标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,所以“A”的编码书写为“U+0041”。

代码点是指可用于编码字符集的数字。编码字符集定义一个有效的代码点范围,但是并不一定将字符分配给所有这些代码点。有效的 Unicode 代码点范围是 U+0000 至 U+10FFFF。Unicode 4.0 将字符分配给一百多万个代码点中的 96,382 代码点。

增补字符是代码点在 U+10000 至 U+10FFFF 范围之间的字符,也就是那些使用原始的 Unicode 的 16 位设计无法表示的字符。从 U+0000 至 U+FFFF 之间的字符集有时候被称为基本多语言面 (BMP)。因此,每一个 Unicode 字符要么属于 BMP,要么属于增补字符。

字符编码方案是从一个或多个编码字符集到一个或多个固定宽度代码单元序列的映射。最常用的代码单元是字节,但是 16 位或 32 位整数也可用于内部处理。UTF-32、UTF-16 和 UTF-8 是 Unicode 标准的编码字符集的字符编码方案。
(所谓编码方案可以视为具体的实现方案,即计算机内部的具体实现方案)

UTF-32 即将每一个 Unicode 代码点表示为相同值的 32 位整数。很明显,它是内部处理最方便的表达方式,但是,如果作为一般字符串表达方式,则要消耗更多的内存。

UTF-16 使用一个或两个未分配的 16 位代码单元的序列对 Unicode 代码点进行编码。值 U+0000 至 U+FFFF 编码为一个相同值的 16 位单元。增补字符编码为两个代码单元,第一个单元来自于高代理范围(U+D800 至 U+DBFF),第二个单元来自于低代理范围(U+DC00 至 U+DFFF)。这在概念上可能看起来类似于多字节编码,但是其中有一个重要区别:值 U+D800 至 U+DFFF 保留用于 UTF-16;没有这些值分配字符作为代码点。这意味着,对于一个字符串中的每个单独的代码单元,软件可以识别是否该代码单元表示某个单单元字符,或者是否该代码单元是某个双单元字符的第一个或第二单元。这相当于某些传统的多字节字符编码来说是一个显著的改进,在传统的多字节字符编码中,字节值 0x41 既可能表示字母“A”,也可能是一个双字节字符的第二个字节。

UTF-8 使用一至四个字节的序列对编码 Unicode 代码点进行编码。U+0000 至 U+007F 使用一个字节编码,U+0080 至 U+07FF 使用两个字节,U+0800 至 U+FFFF 使用三个字节,而 U+10000 至 U+10FFFF 使用四个字节。UTF-8 设计原理为:字节值 0x00 至 0x7F 始终表示代码点 U+0000 至 U+007F(Basic Latin 字符子集,它对应 ASCII 字符集)。这些字节值永远不会表示其他代码点,这一特性使 UTF-8 可以很方便地在软件中将特殊的含义赋予某些 ASCII 字符。

其中特别值得关注的是UTF-8。

二.UFT-8字符的处理

在中文网站的开发中,无论你是否注意到,事实上系统都在使用某一种编码方式来处理中文,如GB2312,UTF-8等,前者是经常使用的代码页,而后者则能够兼容所有的客户访问端,是发展的方向。

在处理过程中常常能够见到的情形是在URL或者POST的数据中,中文被编码成为%E8%87%AA这样的形式,事实上,在.net中要将这些编码还原为UTF-8中文字符并不困难,原理与代码如下:
1.每个中文字符占3个字节并以%开始,因此%E8%87%AA是一个中文字符(自),而事实上E8,87,AA都是16进制的数字,分别为高4位和低4位
2.只要能够将每两个十六进制表示转换成为数字,并存入到byte中,然后将得到的Byte数组用UTF8解码器解码即可


  public class UTF8Operator
  {
   /// <summary>
   /// This method is used to convert the string from "%E6%9D%B1" to UTF8 Chinese Chracter
   /// </summary>
   /// <param name="theInput"></param>
   /// <returns></returns>
   public static string ConvertGB2UTF8(string theInput)
   {
    //Only the string whhich starts with % will be handled
    if (theInput.StartsWith("%"))
    {
     UTF8Encoding utf8 = new UTF8Encoding();

          String theString = theInput;
  
          Byte[] bytes = new byte[theString.Length*3/9];
         
          string [] split = theString.Split(Convert.ToChar("%"));
          int i=0;
          foreach (string s in split)
           {
           string inputStr = s.Trim();
           int theValue = 0;
           if(inputStr.Length == 2)
           {
            //Get the high position
            theValue = theValue + ConvertHexToDec(inputStr.Substring(0,1))*16;
            
            //Get the low position
            theValue = theValue + ConvertHexToDec(inputStr.Substring(1,1));
            //Only the index of bytes array is less than the length
            if (i < bytes.Length)
            {
             bytes = (byte)theValue;             
            }
            i++;         
           }
           }
                   
          //Use the UTF8Encoding object to convert the bytes to string
     string theResult = utf8.GetString(bytes);
     return theResult;     
    }
    else
    {
     return theInput;
    }
   }
   
   //Convert the Hex Code to Dec. A-15, E-14....
   public static int ConvertHexToDec(string theValue)
   {
    string myValue = theValue.Trim().ToUpper();
    
        switch(myValue)      
         {        
           case "1":  
               return 1;
           case "2":  
               return 2;
           case "3":  
               return 3;
           case "4":  
               return 4;
           case "5":  
               return 5;
           case "6":  
               return 6;
           case "7":  
               return 7;
           case "8":  
               return 8;
           case "9":  
               return 9;
           case "A":  
               return 10;
           case "B":  
               return 11;
           case "C":  
               return 12;
           case "D":  
               return 13;
           case "E":  
               return 14;
           case "F":  
               return 15;
           default:           
               return 0;
          }  
   }
  }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值