如何读取没有标题或mimetype的Gzip字符串?使用Python

时间:2012-02-04 17:58:33

标签: python string gzip

我有一个gzip压缩字符串,它是从另一个应用程序创建的。现在我有了字符串(没有连接mimetype或标题),我需要解压缩它。

有没有办法在Python中执行此操作?

[编辑]为了测试我字面上复制然后将字符串粘贴到记事本中,然后重命名为.gz我还通过将字符串本身粘贴到IDLE来测试

我见过的其他例子假设文件类型和mimetype都可用,我所拥有的只是一个大字符串。

使用zlib.decompress(mystring)会出现错误Error -3 while decompressing data: incorrect header check

1 个答案:

答案 0 :(得分:1)

通过@reclosedev确认评论,并添加更多内容:

]之后的字节需要进行base64解码。

结果是,有4个字节构成解压缩数据的长度,作为32位小端二进制数。其余部分是符合RFC-1952的gzip流,可以从1F 8B 08开始识别。解压缩结果看起来像二进制数据,而不是ASCII 1和0的字符串。

代码:

lines = [
    # extracted from the linked csv file 
    "[133,120,696,286]MmEAAB+LCAAAAAAABADtvQdg [BIG snip] a0bokyYQAA",
    "[73,65,564,263]bkgAAB+LCAAAAAAABADtvQdgHE [BIG snip] kgAAA==",
    ]
import zlib, struct
for line in lines:
    print
    b64 = line.split(']')[1]
    raw = b64.decode('base64')
    print "unknown:", repr(raw[:4])
    print "unknown as 32-bit LE int:", struct.unpack("<I", raw[:4])[0]
    ungz = zlib.decompress(raw[4:], 31)
    print len(ungz), "bytes in decompressed data"
    print "first 100:", repr(ungz[:100])

输出:

unknown: '2a\x00\x00'
unknown as 32-bit LE int: 24882
24882 bytes in decompressed data
first 100: '\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xf0\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00'

unknown: 'nH\x00\x00'
unknown as 32-bit LE int: 18542
18542 bytes in decompressed data
first 100: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff
\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x07\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80
\x00\x00\x00'

更新以回应评论

  

要获得我需要的1和0,我只是将其添加到上面的中    cleaning = bin(int(binascii.hexlify(ungz),16))

“只是”?您需要从前面剥离'0b',然后根据需要使用尽可能多的前导零填充前面,以使长度为8的倍数。示例,使用更好的方法:

>>> import binascii
>>> ungz = '\x01\x80'
>>> bin(int(binascii.hexlify(ungz), 16))
'0b110000000'
>>> ''.join('{0:08b}'.format(ord(x)) for x in ungz)
'0000000110000000'

您是否仔细检查过以确保您确实需要'0000000110000000'而不是'1000000000000001'