Skip to main content
 首页 » 编程设计

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

2025年05月04日19kuangbin

我有一个 gzipped 字符串,它是从另一个应用程序创建并存储的。现在我有了字符串(没有附加 mimetype 或 header ),我需要解压缩它。

有没有办法在 Python 中做到这一点?

[EDIT] 为了测试,我直接复制了字符串,然后将其粘贴到记事本中,然后重命名为 .gz 我还通过将字符串本身粘贴到 IDLE 中进行了测试

我见过的其他示例假设文件类型和 mimetype 可用,而我只有一个大字符串。

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

请您参考如下方法:

确认@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' 

更新以回应评论

To get the 1s and 0s I needed I just added this to the above
cleaned = 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'?