unicode跟utf8小结

unicode和utf8小结

首先,unicode和utf-8是两个概念,不能混淆在一起,以python为例,当在字符前面加上u,表示采用unicode编码。比如:

 

>>> val = u'¥'
>>> val
u'\xa5'

 

¥这个字符在unicode中的编码格式是0xa5,所以结果为0xa5。参考: http://zh.wikipedia.org/wiki/%C2%A5

 

如果不在前面加u,表示采用文件制定的编码格式,如果在文件头部加上了# -*- coding: utf-8 -*-,表示utf-8编码。比如:

>>> val = '¥'
>>> val
'\xc2\xa5'

 

那么unicode和utf-8有何区别?又如何对应起来?

 

  • 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
  • 如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
  • 如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
  • 如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
  • 如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;

因 此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节; 根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为1),可判断编码 是否有错误或数据传输过程中是否有错误。

 

下列字节串用来表示一个字符. 用到哪个串取决于该字符在 Unicode 中的序号.

xxx 的位置由字符编码数的二进制表示的位填入. 越靠右的 x 具有越少的特殊意义. 只用最短的那个足够表达一个字符编码数的多字节串. 注意在多字节串中, 第一个字节的开头"1"的数目就是整个串中字节的数目.

例如: Unicode 字符 U+00A9 = 1010 1001 (版权符号) 在 UTF-8 里的编码为:

11000010 10101001 = 0xC2 0xA9

而字符 U+2260 = 0010 0010 0110 0000 (不等于) 编码为:

11100010 10001001 10100000 = 0xE2 0x89 0xA0

这种编码的官方名字拼写为 UTF-8, 其中 UTF 代表 UCS Transformation Format. 请勿在任何文档中用其他名字 (比如 utf8 或 UTF_8) 来表示 UTF-8, 当然除非你指的是一个变量名而不是这种编码本身.

 

 

 

//    	System.out.println(URLDecoder.decode("V%A5%0A.", "unicode"));
//    	System.out.println(URLEncoder.encode("中文", "utf8"));
    
//    	char c = 165;
//    	System.out.println(c);
    	
//    	System.out.println( Integer.toHexString("¥".getBytes("unicode")[0]));
//    	System.out.println( Integer.toHexString("¥".getBytes("unicode")[1]));
//    	System.out.println( Integer.toHexString("¥".getBytes("unicode")[2]));
//    	System.out.println( Integer.toHexString("¥".getBytes("unicode")[3]));
//    	
//    	System.out.println(Integer.toHexString("¥".getBytes("utf8")[0]));
//    	System.out.println(Integer.toHexString("¥".getBytes("utf8")[1]));
    }

 

 

 

# -*- coding: utf-8 -*-


DBOSS={
 "cat":{
    "locations":["localhost:8989"],
    "references":[
        {
            "id":"cacheService",
            "version":"1.0"
        }
    ]
  },
  "mandala":{
    "locations":["localhost:8989"],
    "references":[
        {
            "id":"searchService",
            "version":"1.0"
        },
        {
            "id":"blogQueryService",
            "version":"1.0"
        },
        {
            "id":"commentQueryService",
            "version":"1.0"
        }

    ]
  }
}
from dboss import  DuitangRemoteProxy
proxy = DuitangRemoteProxy(DBOSS)

blogQueryService = proxy.getService('blogQueryService')
val = 'V\xa5\n.'  		#'\xc2\xa5'
print repr(val)
val =  blogQueryService.toPickle(val)
print repr(val)

  
  

 

python中使用 unicode的关键:unicode是一个类,函数unicode(str,"utf8")从utf8编码(当然也可以是别的编码)的字符串str生成 unicode类的对象,而函数unc.encode("utf8")将unicode类的对象unc转换为(编码为)utf8编码(当然也可以是别的编码)的字符串。于是,编写unicode相关程序,需要做的事情是

    * 获取数据(字符串)时,用unicode(str, "utf8")生成unicode对象
    * 在程序中仅使用unicode对象,对程序中出现的字符串常量都以u"字符串"的形式书写
    * 输出时,可将unicode对象转换为任意编码输出,使用str.encode("some_encoding")

 

>>> s = unicode('V\xa5\n.','unicode-escape')
>>> s
u'V\xa5\n.'
>>> type(s)
<type 'unicode'>

 

参考:

http://bytes.com/topic/python/answers/861195-pickling-unicode

http://ubuntuforums.org/showthread.php?t=951337