来自cStringIO的Python“\ x00”填充/ utf-32字符串

时间:2012-04-20 20:53:12

标签: python unicode

通过另一个系统的cStringIO,我通过以下方式编写了一些unicode:

u'content-length'.encode('utf-8')

然后使用unicode( stringio_fd.read(),'utf-8')阅读此内容,我得到:

u'c \ X00 \ X00 \ x00o \ X00 \ X00 \ x00n \ X00 \ X00 \ x00t \ X00 \ X00 \ x00e \ X00 \ X00 \ x00n \ X00 \ X00 \ x00t \ X00 \ X00 \ x00- \ X00 \ X00 \ x00l \ X00 \ X00 \ x00e \ X00 \ X00 \ x00n \ X00 \ X00 \ x00g \ X00 \ X00 \ x00t \ X00 \ X00 \ x00h \ X00 \ X00 \ X00'

在终端上打印上面的内容给了我正确的价值,但当然,我做不了什么有用的事情:

  

打印unicode(“c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00 \ n \ n” - \ X00 \ X00 \ x00l \ X00 \ X00 \ x00e \ X00 \ X00 \ x00n \ X00 \ X00 \ x00g \ X00 \ X00 \ x00t \ X00 \ X00 \ x00h \ X00 \ X00 \ X00" )

     

内容长度

     

打印unicode(“c \ x00 \ x00 \ x00o \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00t \ x00 \ x00 \ x00 \ n \ n” - \ x00 \ x00 \ x00l \ x00 \ x00 \ x00e \ x00 \ x00 \ x00n \ x00 \ x00 \ x00g \ x00 \ x00 \ x00t \ x00 \ x00 \ x00h \ x00 \ x00 \ x00“)== u'content -length'

     

将此字符串转换为等效于u'content-type'的字符串的最快,最便宜的方法是什么?我无法改变cStringIO


更新

虽然philhag的答案是正确的,但似乎问题是:

  

StringIO.StringIO(u'content型 ')。的GetValue()。编码(' UTF-8' )

     

'内容类型'

     

StringIO.StringIO(u'content型 ')。的GetValue()。编码(' UTF-8 ')。解码(' UTF-8' )

     

u'content型'

     

cStringIO.StringIO(u'content型 ')。的GetValue()。编码(' UTF-8 ')。解码(' UTF-8' )

     

u'c \ X00 \ X00 \ x00o \ X00 \ X00 \ x00n \ X00 \ X00 \ x00t \ X00 \ X00 \ x00e \ X00 \ X00 \ x00n \ X00 \ X00 \ x00t \ X00 \ X00 \ x00- \ X00 \ X00 \ x00t \ X00 \ X00 \ x00y \ X00 \ X00 \ x00p \ X00 \ X00 \ x00e \ X00 \ X00 \ X00'

     

cStringIO.StringIO(u'content型 ')。的GetValue()。编码(' UTF-8 ')。解码(' UTF-8 ')。解码(' UTF-32' )

     

u'content型'

2 个答案:

答案 0 :(得分:5)

一路上的事情是将您的值编码为UTF-32。简单地解码它们:

>>> b = u"c\x00\x00\x00o\x00\x00\x00n\x00\x00\x00t\x00\x00\x00e\x00\x00\x00\
... n\x00\x00\x00t\x00\x00\x00-\x00\x00\x00l\x00\x00\x00e\x00\x00\x00\
... n\x00\x00\x00g\x00\x00\x00t\x00\x00\x00h\x00\x00\x00"
>>> b.decode('utf-32')
u'content-length'

答案 1 :(得分:4)

根本原因是cStringIO.StringIO(unicode_object)产生了废话。

docs.python.org上的current 2.X docs

  

与StringIO模块不同,此模块无法接受Unicode   无法编码为纯ASCII字符串的字符串。

这是无益的,也是不正确的;见下文。 CPython 2.7.2和2.6.6的win32安装程序随附的文档的chm版本遵循以下句子:

  

使用Unicode字符串参数调用StringIO()会填充   具有Unicode字符串的缓冲区表示的对象而不是   编码字符串。

这是对行为的正确描述(见下文)。这种行为并不精彩。我无法想象从网络文档中删除该句子的充分理由。

表现不好:

Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
>>> import StringIO, cStringIO, sys
>>> StringIO.StringIO(u"fubar").getvalue()
u'fubar' <<=== unicode object
>>> cStringIO.StringIO(u"fubar").getvalue()
'f\x00u\x00b\x00a\x00r\x00' <<=== str object
cStringIO.StringIO(u"\u0405\u0406").getvalue()
'\x05\x04\x06\x04' <<=== "accepts"
>>> sys.maxunicode
65535 # your sender presumably emits 1114111 (wide unicode)
>>> sys.byteorder
'little'

所以一般来说,所有人需要做的就是知道/猜测发送者的Python的字节顺序和unicode-width,并用UTF-(16|32)-(B|L)E解码混乱。

在你的情况下,发件人是拜占庭人;例如u'content-length'.encode('utf-8')str对象'content-length',它与您开始时的内容非常相似。此外,foo.encode(utf8').decode('utf8')会生成foo或例外。