gpt4 book ai didi

python - python中的zlib解压

转载 作者:太空狗 更新时间:2023-10-29 18:14:23 25 4
gpt4 key购买 nike

好的,所以我有一些由 python (2.6) zlib.compress() 函数压缩的数据流。当我尝试解压缩它们时,其中一些不会解压缩(zlib 错误 -5,这似乎是一个“缓冲区错误”,不知道该怎么做)。起初,我以为我已经完成了,但我意识到所有我无法解压的都是从0x78DA开始的(工作的是0x789C),我环顾四周,似乎是一种不同的zlib压缩——魔数(Magic Number)根据使用的压缩而变化。我可以用什么来解压缩文件?我被灌水了吗?

最佳答案

根据 RFC 1950 ,“OK” 0x789C 和“坏” 0x78DA 之间的区别在于 FLEVEL 位字段:

  FLEVEL (Compression level)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:

0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm

The information in FLEVEL is not needed for decompression; it
is there to indicate if recompression might be worthwhile.

“OK”用2,“bad”用3。所以这种差异本身不是问题。

为了更进一步,您可以考虑为每个压缩和(尝试)解压缩提供以下信息:什么平台、什么版本的 Python、什么版本的 zlib 库、用于调用 zlib 模块的实际代码是什么。还提供来自失败的解压缩尝试的完整回溯和错误消息。您是否尝试过使用任何其他 zlib 读取软件解压缩失败的文件?有什么结果?请澄清您必须处理的内容:“我被冲洗了吗?”意味着您无权访问原始数据?它是如何从流到文件的?你有什么保证数据在传输过程中没有被破坏?

UPDATE 基于在您的自我回答中发布的部分说明的一些观察结果:

您正在使用 Windows。 Windows 在读写文件时区分二进制模式和文本模式。在文本模式下读取时,Python 2.x 将 '\r\n' 更改为 '\n',写入时将 '\n' 更改为 '\r\n'。在处理非文本数据时,这不是一个好主意。更糟糕的是,在文本模式下阅读时, '\x1a' 又名 Ctrl-Z 被视为文件结尾。

要压缩文件:
# imports and other superstructure left as a exercise
str_object1 = open('my_log_file', 'rb').read()
str_object2 = zlib.compress(str_object1, 9)
f = open('compressed_file', 'wb')
f.write(str_object2)
f.close()

要解压缩文件:
str_object1 = open('compressed_file', 'rb').read()
str_object2 = zlib.decompress(str_object1)
f = open('my_recovered_log_file', 'wb')
f.write(str_object2)
f.close()

旁白:最好使用 gzip 模块,这样您就不必考虑像文本模式这样的麻烦事,代价是额外的标题信息需要几个字节。

如果您一直在压缩代码中使用 'rb' 和 'wb' 而不是在您的解压缩代码中 [不太可能?],那么您并没有被灌输,您只需要充实上面的解压代码并继续使用。

请仔细注意以下未经检验的想法中“可能”、“应该”等的使用。

如果您没有在压缩代码中使用 'rb' 和 'wb',那么您自己处理的可能性相当高。

如果您的原始文件中有任何 '\x1a' 实例,那么第一个这样的数据之后的任何数据都会丢失——但在这种情况下,它不应该在解压时失败(IOW 这种情况与您的症状不符)。

如果 Ctrl-Z 是由 zlib 本身生成的,这应该会在尝试解压缩时导致早期 EOF,这当然会导致异常。在这种情况下,您可以通过以二进制模式读取压缩文件,然后将 '\r\n' 替换为 '\n' [即在没有 Ctrl-Z -> EOF 噱头的情况下模拟文本模式]。解压结果。 编辑 以文本模式将结果写出。 结束编辑

UPDATE 2 我可以使用以下脚本重现您的症状——任何级别 1 到 9:
import zlib, sys
fn = sys.argv[1]
level = int(sys.argv[2])
s1 = open(fn).read() # TEXT mode
s2 = zlib.compress(s1, level)
f = open(fn + '-ct', 'w') # TEXT mode
f.write(s2)
f.close()
# try to decompress in text mode
s1 = open(fn + '-ct').read() # TEXT mode
s2 = zlib.decompress(s1) # error -5
f = open(fn + '-dtt', 'w')
f.write(s2)
f.close()

注意:您需要使用一个相当大的文本文件(我使用了一个 80kb 的源文件)来确保解压结果将包含一个“\x1a”。

我可以用这个脚本恢复:
import zlib, sys
fn = sys.argv[1]
# (1) reverse the text-mode write
# can't use text-mode read as it will stop at Ctrl-Z
s1 = open(fn, 'rb').read() # BINARY mode
s1 = s1.replace('\r\n', '\n')
# (2) reverse the compression
s2 = zlib.decompress(s1)
# (3) reverse the text mode read
f = open(fn + '-fixed', 'w') # TEXT mode
f.write(s2)
f.close()

注意:如果原始文件中有一个 '\x1a' aka Ctrl-Z 字节,并且该文件以文本模式读取,则该字节和所有后续字节将不会包含在压缩文件中,因此无法恢复.对于文本文件(例如源代码),这根本没有损失。对于二进制文件,您很可能会被灌水。

更新 3 [根据最新发现问题涉及加密/解密层]:

“错误 -5”消息表明您尝试解压缩的数据在压缩后已被破坏。如果它不是由在文件上使用文本模式引起的,那么显然(?)会落在您的解密和加密包装器上。如果您需要帮助,则需要透露这些包装器的来源。事实上,您应该尝试做的是(就像我所做的那样)将一个小脚本放在一起,在多个输入文件上重现问题。其次(就像我一样)看看你是否可以在什么条件下逆转这个过程。如果您需要第二阶段的帮助,您需要透露问题重现脚本。

关于python - python中的zlib解压,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1316357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com