如何从zlib压缩字符串中移除头部?
我正在使用 zlib
来压缩字符串,并且使用了一个强度为 9 的 字典,这是我的脚本:
import zlib
__doc__ = """
rly this small py em ell thon... !? ha he hahaha hehehe h4ck3r wassup how ar u let's go lets go common c'mon...!!! ad
"""
class Compressor(object):
def __init__(self, seed):
c = zlib.compressobj(9)
d_seed = c.compress(seed)
d_seed += c.flush(zlib.Z_SYNC_FLUSH)
self.c_context = c.copy()
d = zlib.decompressobj()
d.decompress(d_seed)
while d.unconsumed_tail:
d.decompress(d.unconsumed_tail)
self.d_context = d.copy()
def compress(self, text):
c = self.c_context.copy()
t = c.compress(text)
t2 = c.flush(zlib.Z_FINISH)
return t + t2
def decompress(self, ctext):
d = self.d_context.copy()
t = d.decompress(ctext)
while d.unconsumed_tail:
t += d.decompress(d.unconsumed_tail)
return t
c = Compressor(__doc__)
compressed_string = c.compress(string)
print compressed_string
string = "I installed python, and it's very nice and easy to use!"
compressed = c.compress(string)
print c.decompress(compressed)
我的问题是:从得到的 compressed_string
中,怎么去掉多余的部分,比如头部和最后的 4 个 ADLER 字节,这些在解压时会被附加上?如果我的定义有错,请纠正我。
比如说 12h3d78e23gdh278qs98qwjsj89qs1234
(其中 12
是理论上的 2 字节头部,1234
是理论上的 ADLER
部分在字符串的末尾),这段字符串应该变成 h3d78e23gdh278qs98qwjsj89qs
,然后在 zlib 解压时会用类似的方式重建。
to_decompress = '12',compressed,'1234'
c.decompress(to_decompress)
1 个回答
1
你已经有效地去掉了头部信息,因为它就在d_seed
的前两个字节里。你不需要也不应该去掉Adler-32校验,因为如果你正确地重建压缩流,Adler-32会提供完整性检查。
你只需要把d_seed
放在传输数据的前面,然后正常解压缩结果就可以了。
如果你使用的是Python 3.3或更高版本,做这件事的更好方法是用zlib来帮你处理字典。zlib.compressobj()
和zlib.decompressobj()
的最后一个参数可以是字典。这样你还可以得到提供的字典的完整性检查,帮助确认在解压缩时使用的字典和压缩时的一样。这样处理后的流就是一个标准的zlib流,使用了字典,更加便于移植和识别。
如果你真的想节省六个字节(不推荐,因为这样会失去完整性检查),或者其实只想节省四个字节,因为你已经去掉了头部信息,那么可以在zlib.*compressobj()
中把wbits
参数设置为-15
。这样会去掉zlib的头部和尾部。(这也需要3.3版本。)