Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7194138
  • 博文数量: 510
  • 博客积分: 12019
  • 博客等级: 上将
  • 技术积分: 6836
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-01 16:46
文章分类

全部博文(510)

文章存档

2022年(2)

2021年(6)

2020年(59)

2019年(4)

2018年(10)

2017年(5)

2016年(2)

2015年(4)

2014年(4)

2013年(16)

2012年(47)

2011年(65)

2010年(46)

2009年(34)

2008年(52)

2007年(52)

2006年(80)

2005年(22)

分类: Python/Ruby

2012-08-24 15:52:37

服务器可很方面表示二进制数据,但是客户端存在问题。主要思想:utf8-->unicode值;然后通过fromCharCode拼串。下面在chrome下测试通过

点击(此处)折叠或打开

  1. function binayUtf8ToString(buf, begin){
  2.   var i = 0;
  3.   var pos = 0;
  4.   var str ="";
  5.   var unicode = 0 ;
  6.   var flag = 0;
  7.   for (pos = begin; pos < buf.length;){
  8.     flag= buf[pos];
  9.     if ((flag >>>7) === 0 ) {
  10.       str+= String.fromCharCode(buf[pos]);
  11.       pos += 1;
  12.       
  13.     }
  14.     else if ((flag &0xFC) === 0xFC ){
  15.       unicode = (buf[pos] & 0x3) << 30;
  16.       unicode |= (buf[pos+1] & 0x3F) << 24;
  17.       unicode |= (buf[pos+2] & 0x3F) << 18;
  18.       unicode |= (buf[pos+3] & 0x3F) << 12;
  19.       unicode |= (buf[pos+4] & 0x3F) << 6;
  20.       unicode |= (buf[pos+5] & 0x3F);
  21.       str+= String.fromCharCode(unicode) ;
  22.       pos += 6;
  23.       
  24.     }else if ((flag &0xF8) === 0xF8 ){
  25.       unicode = (buf[pos] & 0x7) << 24;
  26.       unicode |= (buf[pos+1] & 0x3F) << 18;
  27.       unicode |= (buf[pos+2] & 0x3F) << 12;
  28.       unicode |= (buf[pos+3] & 0x3F) << 6;
  29.       unicode |= (buf[pos+4] & 0x3F);
  30.       str+= String.fromCharCode(unicode) ;
  31.       pos += 5;
  32.       
  33.     }
  34.     else if ((flag &0xF0) === 0xF0 ){
  35.       unicode = (buf[pos] & 0xF) << 18;
  36.       unicode |= (buf[pos+1] & 0x3F) << 12;
  37.       unicode |= (buf[pos+2] & 0x3F) << 6;
  38.       unicode |= (buf[pos+3] & 0x3F);
  39.       str+= String.fromCharCode(unicode) ;
  40.       pos += 4;
  41.       
  42.     }
  43.    
  44.     else if ((flag &0xE0) === 0xE0 ){
  45.       unicode = (buf[pos] & 0x1F) << 12;;
  46.       unicode |= (buf[pos+1] & 0x3F) << 6;
  47.       unicode |= (buf[pos+2] & 0x3F);
  48.       str+= String.fromCharCode(unicode) ;
  49.       pos += 3;
  50.       
  51.     }
  52.     else if ((flag &0xC0) === 0xC0 ){ //110
  53.       unicode = (buf[pos] & 0x3F) << 6;
  54.       unicode |= (buf[pos+1] & 0x3F);
  55.       str+= String.fromCharCode(unicode) ;
  56.       pos += 2;
  57.       
  58.     }
  59.     else{
  60.       str+= String.fromCharCode(buf[pos]);
  61.       pos += 1;
  62.     }
  63.  }
  64.  return str;
  65.   
  66. }



附加:

unicode到utf8

点击(此处)折叠或打开

  1. function unicodeToUtf8(str) {
  2.     var i, len, ch;
  3.     var utf8Str = "";
  4.     len = str.length;
  5.     for (i = 0; i < len; i++) {
  6.         ch = str.charCodeAt(i);
  7.         
  8.         if ((ch >= 0x0) && (ch <= 0x7F)) {
  9.             utf8Str += str.charAt(i);
  10.             
  11.         } else if ((ch >= 0x80) && (ch <= 0x7FF)){
  12.             utf8Str += String.fromCharCode(0xc0 | ((ch >> 6) & 0x1F));
  13.             utf8Str += String.fromCharCode(0x80 | (ch & 0x3F));
  14.             
  15.         } else if ((ch >= 0x800) && (ch <= 0xFFFF)){
  16.             utf8Str += String.fromCharCode(0xe0 | ((ch >> 12) & 0xF));
  17.             utf8Str += String.fromCharCode(0x80 | ((ch >> 6) & 0x3F));
  18.             utf8Str += String.fromCharCode(0x80 | (ch & 0x3F));
  19.             
  20.         } else if ((ch >= 0x10000) && (ch <= 0x1FFFFF)){
  21.            utf8Str += String.fromCharCode(0xF0 | ((ch >> 18) & 0x7));
  22.            utf8Str += String.fromCharCode(0x80 | ((ch >> 12) & 0x3F));
  23.            utf8Str += String.fromCharCode(0x80 | ((ch >> 6) & 0x3F));
  24.            utf8Str += String.fromCharCode(0x80 | (ch & 0x3F));
  25.            
  26.         } else if ((ch >= 0x200000) && (ch <= 0x3FFFFFF)){
  27.            utf8Str += String.fromCharCode(0xF8 | ((ch >> 24) & 0x3));
  28.            utf8Str += String.fromCharCode(0x80 | ((ch >> 18) & 0x3F));
  29.            utf8Str += String.fromCharCode(0x80 | ((ch >> 12) & 0x3F));
  30.            utf8Str += String.fromCharCode(0x80 | ((ch >> 6) & 0x3F));
  31.            utf8Str += String.fromCharCode(0x80 | (ch & 0x3F));
  32.            
  33.         } else if ((ch >= 0x4000000) && (ch <= 0x7FFFFFFF)){
  34.            utf8Str += String.fromCharCode(0xFC | ((ch >> 30) & 0x1));
  35.            utf8Str += String.fromCharCode(0x80 | ((ch >> 24) & 0x3F));
  36.            utf8Str += String.fromCharCode(0x80 | ((ch >> 18) & 0x3F));
  37.            utf8Str += String.fromCharCode(0x80 | ((ch >> 12) & 0x3F));
  38.            utf8Str += String.fromCharCode(0x80 | ((ch >> 6 ) & 0x3F));
  39.            utf8Str += String.fromCharCode(0x80 | (ch & 0x3F));
  40.            
  41.         }
  42.             
  43.     }
  44.     return utf8Str;
  45. };




以下文章来自互联网
    最近在用VC++开发一个小工具,平时用惯了.NET,用起VC++最郁闷的就是字符串处理。当然最最让人难于琢磨的就是字符集,编码之间的转换。通过这 几天的研究,终于明白了Unicode和UTF-8之间编码的区别。Unicode是一个字符集,而UTF-8是Unicode的其中一 种,Unicode是定长的都为双字节,而UTF-8是可变的,对于汉字来说Unicode占有的字节比UTF-8占用的字节少1个字节。Unicode 为双字节,而UTF-8中汉字占三个字节。
                       
http://xdotnet.cnblogs.com
    UTF-8编码字符理论上可以最多到6个字节长,然而16位BMP(
Basic Multilingual Plane)字符最多只用到3字节长。下面看一下UTF-8编码表:

        U-00000000 - U-0000007F: 0xxxxxxx
        U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
        U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
        U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
        U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


    xxx 的位置由字符编码数的二进制表示的位填入, 越靠右的 x 具有越少的特殊意义,只用最短的那个足够表达一个字符编码数的多字节串。 注意在多字节串中, 第一个字节的开头"1"的数目就是整个串中字节的数目。而第一行中以0开头,是为了兼容ASCII编码,为一个字节,第二行就为双字节字符串,第三行为3 字节,如汉字就属于这种,以此类推。(个人认为:其实我们可以简单的把前面的1的个数看成字节数)
                         http://xdotnet.cnblogs.com
    为了要将Unicode转换为UTF-8,当然要知道他们的区别到底在什么地方。下面来看一下,在Unicode中的编码是怎样转换成UTF-8的,在UTF-8中,如果一个字符的字节小于0x80(128)则为ASCII字符,占一个字节,可以不用转换,因为UTF-8兼容ASCII编码。假如在Unicode中汉字“你”的编码为“u4F60”,把它转换为二进制为100111101100000,然后按照UTF-8的方法进行转换。可以将Unicode二进制从地位往高位取出二进制数字,每次取6位,如上述的二进制就可以分别取出为如下所示的格式,前面按格式填补,不足8位用0填补。

      
           unicode:  100111101100000                  4F60

           utf-8:    11100100,10111101,10100000       E4BDA0


    从上面就可以很直观的看出Unicode到UTF-8之间的转换,当然知道了UTF-8的格式后,就可以进行逆运算,就是按照格式把它在二进制中的相应位置上取出,然后在转换就是所得到的Unicode字符了(这个运算可以通过“位移”来完成)。
                     
http://xdotnet.cnblogs.com
    如上述的“你”的转换,由于其值大于0x800小于0x10000,因此可以判断为三字节存储,则最高位需要向右移“12”位再根据三字节格式的最高位为 11100000(0xE0)求或(|)就可以得到最高位的值了。同理第二位则是右移“6”位,则还剩下最高位和第二位的二进制值,可以通过与 111111(0x3F)求按位于(&)操作,再和11000000(0x80)求或(|)。第三位就不用移位了,只要直接取最后六位(与 111111(ox3F)取&),在与11000000(0x80)求或(|)。OK了,转换成功!在VC++中的代码如下所示(Unicode到UTF-8的转换)。

        1 const wchar_t pUnicode = L"";
        2 char utf8[3+1];
        3 memset(utf8,0,4);
        4 utf8[0= 0xE0|(pUnicode>>12);
        5 utf8[1= 0x80|((pUnicode>>6)&0x3F);
        6 utf8[2= 0x80|(pUnicode&0x3F);
        7 utf8[3= "\0";
        8 //char[4]就是UTF-8的字符“你”了。

    当然在UTF-8到Unicode的转换也是通过移位等来完成的,就是把UTF-8那些格式相应的位置的二进制数给揪出来。在上述例子中“你”为三个字节,因此要每个字节进行处理,有高位到低位进行处理。在UTF-8中“你”为
11100100,10111101,10100000。从高位起即第一个字节11100100就是把其中的"0100"给取出来,这个很简单只要和11111(0x1F)取与(&),由三字节可以得知最到位肯定位于12位之前,因为每次取六位。所以还要将得到的结果左移12位,最高位也就这样完成了0100,000000,000000。而第二位则是要把“111101”给取出来,则只需将第二字节10111101 和111111(0x3F)取与(&)。在将所得到的结果左移6位与最高字节所得的结果取或(|),第二位就这样完成了,得到的结果为 0100,111101,000000。以此类推最后一位直接与111111(0x3F)取与(&),再与前面所得的结果取或(|)即可得到结果 0100,111101,100000。OK,转换成功!在VC++中的代码如下所示(UTF-8Unicode的转换)。

    1 //UTF-8格式的字符串
    2 const char* utf8 = "";
    3 wchar_t unicode;
    4 unicode = (utf8[0& 0x1F<< 12;
    5 unicode |= (utf8[1& 0x3F<< 6;
    6 unicode |= (utf8[2& 0x3F);
    7 //unicode is ok!
                            http://xdotnet.cnblogs.com
    当然在编程过程中不可能只转换一个字符,这里需要注意的是字符的长度一定要算清楚,不然会带来...以上就是我这几天研究的结果,至于Unicode的转换为GB2312在MFC中Windows有自带的API(WideCharToMultiByte)可以转换。这样也就能够将UTF-8格式转换为GB2312了,这里就不再赘述,如果大家有更好的方法希望指教。
阅读(16633) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~