使用 zlib 重新压缩解压后的字符串
Re-compress a decompressed string with zlib
我有一个编码字符串,我在不知道它最初是如何编码的情况下设法解码的。这就是我设法解码的方式:
original_str = "LONG_SNIP" # Is clearly a base64 string
decoded_str = base64.b64decode(original_str) # Becomes unreadable mess
decompressed_str = zlib.decompress(decoded_str, -15) # Plain text, success
我想指出 zlib 参数“-15”是强制性的(-8 和 -15 之间的任何参数都有效)
但是,如果我想将纯文本字符串编码成完全相同的格式,以便上面的代码也能成功解码该格式,我 运行 就会遇到问题。
我查看了 zlib 文档并尝试了 zlib.compress,还创建了一个 compressobj 并尝试用它进行压缩,但没有成功。
这个'-15'值似乎不能输入任何函数来反转我原来做的解压。
这也是我尝试过的方法,但我得到的是空白输出:
compress = zlib.compressobj( 1, zlib.DEFLATED, -15, zlib.DEF_MEM_LEVEL, 0 )
deflated = compress.compress(string_to_compress)
encoded = base64.b64encode(deflated)
print(encoded)
问题:
整数参数是什么意思,为什么 -8 和 -15 之间的所有值都给出相同的精确输出?
更重要的是,我该如何逆转减压?
非常感谢回答,谢谢!
zlib.decompress()
的第二个参数是 wbits 参数。来自 documentation:
The wbits parameter controls the size of the history buffer (or “window size”), and what header and trailer format is expected. It is similar to the parameter for compressobj()
, but accepts more ranges of values:
- [...]
- −8 to −15: Uses the absolute value of wbits as the window size logarithm. The input must be a raw stream with no header or trailer.
- [...]
When decompressing a stream, the window size must not be smaller than the size originally used to compress the stream; using a too-small value may result in an error
exception.
负值仅表示数据流中没有头部或尾部。
因此,如果 -8 和 -15 之间的任何值都有效,则压缩的 window 大小从一开始就非常小。更大的 window 大小需要更多的内存用于更大的历史缓冲区,但可以使解压缩速度更快。唯一的要求是它应该等于或大于用于压缩数据的数据块,否则将无法再找到对压缩流中使用的先前数据块的引用(我想,我确定 Mark Adler如果我错了,会纠正我的。
zlib manual 似乎暗示 wbits=8
实际上会自动替换为 wbits=9
,并且可能 -8
.
也会发生同样的情况
这转换为 zlib.compresobj()
wbits 值介于 -9 和 -15 之间;再次来自文档:
- −9 to −15: Uses the absolute value of wbits as the window size logarithm, while producing a raw output stream with no header or trailing checksum.
用最小的 window 大小压缩应该足够了:
compressor = zlib.compressobj(-1, zlib.DEFLATED, -9)
compressed = compressor.compress(data_to_compress) + compressor.flush()
演示:
>>> import zlib
>>> compressor = zlib.compressobj(-1, zlib.DEFLATED, -9)
>>> compressor.compress('foo bar baz') + compressor.flush()
'K\xcb\xcfWHJ,\x02\xe2*\x00'
>>> zlib.decompress(_, -8)
'foo bar baz'
我有一个编码字符串,我在不知道它最初是如何编码的情况下设法解码的。这就是我设法解码的方式:
original_str = "LONG_SNIP" # Is clearly a base64 string
decoded_str = base64.b64decode(original_str) # Becomes unreadable mess
decompressed_str = zlib.decompress(decoded_str, -15) # Plain text, success
我想指出 zlib 参数“-15”是强制性的(-8 和 -15 之间的任何参数都有效)
但是,如果我想将纯文本字符串编码成完全相同的格式,以便上面的代码也能成功解码该格式,我 运行 就会遇到问题。
我查看了 zlib 文档并尝试了 zlib.compress,还创建了一个 compressobj 并尝试用它进行压缩,但没有成功。
这个'-15'值似乎不能输入任何函数来反转我原来做的解压。
这也是我尝试过的方法,但我得到的是空白输出:
compress = zlib.compressobj( 1, zlib.DEFLATED, -15, zlib.DEF_MEM_LEVEL, 0 )
deflated = compress.compress(string_to_compress)
encoded = base64.b64encode(deflated)
print(encoded)
问题:
整数参数是什么意思,为什么 -8 和 -15 之间的所有值都给出相同的精确输出?
更重要的是,我该如何逆转减压?
非常感谢回答,谢谢!
zlib.decompress()
的第二个参数是 wbits 参数。来自 documentation:
The wbits parameter controls the size of the history buffer (or “window size”), and what header and trailer format is expected. It is similar to the parameter for
compressobj()
, but accepts more ranges of values:
- [...]
- −8 to −15: Uses the absolute value of wbits as the window size logarithm. The input must be a raw stream with no header or trailer.
- [...]
When decompressing a stream, the window size must not be smaller than the size originally used to compress the stream; using a too-small value may result in an
error
exception.
负值仅表示数据流中没有头部或尾部。
因此,如果 -8 和 -15 之间的任何值都有效,则压缩的 window 大小从一开始就非常小。更大的 window 大小需要更多的内存用于更大的历史缓冲区,但可以使解压缩速度更快。唯一的要求是它应该等于或大于用于压缩数据的数据块,否则将无法再找到对压缩流中使用的先前数据块的引用(我想,我确定 Mark Adler如果我错了,会纠正我的。
zlib manual 似乎暗示 wbits=8
实际上会自动替换为 wbits=9
,并且可能 -8
.
这转换为 zlib.compresobj()
wbits 值介于 -9 和 -15 之间;再次来自文档:
- −9 to −15: Uses the absolute value of wbits as the window size logarithm, while producing a raw output stream with no header or trailing checksum.
用最小的 window 大小压缩应该足够了:
compressor = zlib.compressobj(-1, zlib.DEFLATED, -9)
compressed = compressor.compress(data_to_compress) + compressor.flush()
演示:
>>> import zlib
>>> compressor = zlib.compressobj(-1, zlib.DEFLATED, -9)
>>> compressor.compress('foo bar baz') + compressor.flush()
'K\xcb\xcfWHJ,\x02\xe2*\x00'
>>> zlib.decompress(_, -8)
'foo bar baz'