类型:Python,创建时间:Jan. 1, 2012, 9:15 p.m.
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/56/。
我经常用Python做一些字符串处理,一直以为只有str
类型有decode()
方法,而unicode
类型没有,只有unicode
类型有encode()
方法而str
类型没有。后来才突然注意原来这两种类型都有这两个方法,只是用了可能会出错。比如:
u"国将不国".decode("gbk") "国将不国".encode("gbk")
在Windows下通常会报错。既然如此,为啥给这两种类型都安上decode()
和encode()
呢?疑问疑问!
decode()
和encode()
所支持的编码名字可以在Python的encodings
包下找到,路径一般是:
C:\Python26\Lib\encodings /usr/lib/python2.6/encodings
其中可以找到gbk,utf-8,big5编码。还有一个aliases.py
,里面记录了各种编码的别称,比如下面三条语句等价:
u"国将不国".encode("utf-8") u"国将不国".encode("u8") u"国将不国".encode("utf8")
再仔细找一找,发现这几个编码挺有意思的:
base64 | bz2 | hex | idna | punycode | quopri | uu |
raw_unicode_escape | rot_13 | string_escape | undefined | unicode_internal | utf_8_sig | zlib |
base64
编码,顾名思义,它相互转换普通的字符串与base64字符串:
>>> "国将不国".encode("base64") 'ufq9q7K7ufo=\n' >>> print 'ufq9q7K7ufo=\n'.decode("base64") 国将不国
bz2
, zlib
编码则分别使用bz2
, zlib
两种压缩算法对字符串进行压缩与解压缩:
>>> ("f"*1024*1024).encode("bz2") 'BZh91AY&SY\x99C\xc0+\x00\x08\nA\x00\x80\x04
x01x00x00x08 x000xccx05Ixeaqx06x01@\x1e.\xe4\x8ap\xa1!2\x87\x80V'
>>> print len('BZh91AY&SY\x99C\xc0+\x00\x08\nA\x00\x80\x04\x01
\x00\x00\x08 \x000\xcc\x05I\
xeaq\x06\x01@
x1e.xe4x8apxa1!2x87x80V'.decode("bz2"))
1048576
这里str.decode()
和str.encode()
两个方法都用到了。原来如此!
hex
编码将字符串转换成十六进制形式:
>>> '国将不国'.encode('hex') 'b9fabdabb2bbb9fa' >>> print 'b9fabdabb2bbb9fa'.decode("hex") 国将不国
ps:之前我还傻傻地写过tohex(s)函数,现在才发现原来我重新发明了轮子
idna
与punycode
据说用于支持Internationalized Domain Names。中文域名?呼唤大牛解答。
quopri
与base64
经常相提并论,因为它们经常用于邮件的编码。最早的Email系统不大支持非ascii字符集。在发送中文邮件的时候,要使用quopri
编码或者base64
编码先处理一下。比如:
>>> "国将不国" '\xb9\xfa\xbd\xab\xb2\xbb\xb9\xfa' >>> "国将不国".encode("quopri") '=B9=FA=BD=AB=B2=BB=B9=FA'
quopri
编码实际上就是hex
编码的变形。与base64
相比较,使用quopri
编码转换后的文本一般会比较大一点。不过,如果邮件里ascii占比较大的比例,即使对方的邮件客户端很古老,使用quopri
编码也很容易看清楚文本。
raw_unicode_escape
与string_escape
用于将字符串转换成"程序员的写法",先看一下repr()
函数怎么样处理字符串:
>>> print repr(u"国将不国") u'\u56fd\u5c06\u4e0d\u56fd' >>> print repr("国将不国") '\xb9\xfa\xbd\xab\xb2\xbb\xb9\xfa'
这两种编码与repr()
类似:
>>> print u"国将不国".encode("raw_unicode_escape") \u56fd\u5c06\u4e0d\u56fd >>> print "国将不国".encode("string_escape") \xb9\xfa\xbd\xab\xb2\xbb\xb9\xfa
差别在于没了引号与前缀'u'
。输出结果都是str
类型。
与上面两种编码对比的是unicode_internal
,它用于将字符串转换成"机器的写法",说白了就是把存储unicode
字符串的内存拷贝出来:
>>> u'国将不国'.encode('unicode-internal') '\xfdV\x06\\\rN\xfdV'
用timeit
测试了一下,貌似raw_unicode_escape
与unicode-internal
的速度相差不大,虽然unicode-internal
会快一点点。
undefined编码是一种总给你报错的编码。
>>> "国将不国".encode("undefined") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python26\lib\encodings\undefined.py", line 19, in encode raise UnicodeError("undefined encoding") UnicodeError: undefined encoding >>> "国将不国".decode("undefined") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python26\lib\encodings\undefined.py", line 22, in decode raise UnicodeError("undefined encoding") UnicodeError: undefined encoding
utf_8_sig
与utf-8
编码差不多。只是在编码的加入BOM,解码的时候会忽略BOM。BOM(Byte Order Mark)用于标识字节序。讨论字节序太无聊了,详情可以参阅:
最后,rot_13
是可算是最大名鼎鼎的加密算法了,以其超弱的加密程度著称。它的加密规则是:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
上下两行字母两两相互替换,A
替换成N
,B
替换成O
,N
替换成A
,O
替换成B
,依此类推。。。。空格、标点符号都不变,碰到非ASCII码可能会报错。
从字母表上看来就是字母往后挪了13位,所以叫"rotate by 13 places"。据说,这种加密方法是凯撒发明的。之所以是13位是因为:
>>> "fish/panda/kaola".encode("rot-13") 'svfu/cnaqn/xnbyn' >>> "fish/panda/kaola".encode("rot-13").encode("rot-13") 'fish/panda/kaola'
注意我们并没有用到decode()
。因为rot13+rot13=rot26
,rot26
就是啥都不变。
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/56/。
暂时还没有任何评论。