在Python中用gzip或zlib压缩字符串为什么我缺少“H4sIAAAAAAAA/”bi

2024-09-28 23:37:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python压缩一个字符串,但结果并不是我所期望的那样。在

我试图压缩的字符串例如:

<?xml version='1.0' encoding='UTF-8'?>

我的最终结果应该是:

^{pr2}$

第一次尝试:

base64.b64encode(gzip.compress("<?xml version='1.0' encoding='UTF-8'?>".encode('utf-8')))

结果:

b'H4sIAHDj6lsC/7Oxr8jNUShLLSrOzM+zVTfUM1BXSM1Lzk/JzEu3VQ8NcdO1ULe3AwBHQvxaJgAAAA=='

结果几乎就是我要找的,但是标题部分是不同的。两个结果(我的结果和预期的结果)都解压缩到同一个字符串,所以它们似乎都可以工作。我仍然想知道为什么在base64压缩字符串中没有得到正确的头。在

我能用zlib得到更好的结果吗?我试过了,但得到了完全不同的结果,在减压时也有效。在


Tags: 字符串versionxmlcompressutfencodingencodegzip
1条回答
网友
1楼 · 发布于 2024-09-28 23:37:14

你有完全相同的压缩数据流。唯一的区别是您期望的数据流具有MTIME field of the header set to 0 and the XFL flag set to 0, not 2

>>> from base64 import b64decode
>>> expected = b64decode('H4sIAAAAAAAA/7Oxr8jNUShLLSrOzM+zVTfUM1BXSM1Lzk/JzEu3VQ8NcdO1ULe3AwBHQvxaJgAAAA==')
>>> actual = b64decode('H4sIAHDj6lsC/7Oxr8jNUShLLSrOzM+zVTfUM1BXSM1Lzk/JzEu3VQ8NcdO1ULe3AwBHQvxaJgAAAA==')
>>> expected[:4] == actual[:4]  # identification, compression method and flag match
True
>>> expected[4:8], actual[4:8]  # mtime bytes differ, zero vs. current time
(b'\x00\x00\x00\x00', b'p\xe3\xea[')
>>> from datetime import datetime
>>> print(datetime.fromtimestamp(int.from_bytes(actual[4:8], 'little')))
2018-11-13 14:45:04
>>> expected[8], actual[8]  # XFL is set to 2 in the actual output
(0, 2)
>>> expected[9], actual[9]  # OS set to *unknown* in both
(255, 255)
>>> expected[10:] == actual[10:]  # compressed data payload is the same
True

gzip.compress()函数只使用^{} class来进行实际的压缩,只要mtime参数保留为默认值None,它就会使用time.time()作为MTIME字段。在

我不认为这两个字符串会产生完全相同的解压缩数据。在

如果必须具有相同的输出,那么最简单的方法是只替换头

^{pr2}$

上面的头文件将替换现有的头文件,将重要的部分设置为与预期输出相同的值;MTIME和XFL标志都设置为0。请注意,当您使用gzip.compress()时,只有MTIME字节会发生变化,并且在解压缩时并没有实际使用XFL字段。在

虽然可以使用gzip.GzipFile()类生成MTIME设置为0的压缩输出(pass in mtime=0),但不能更改XFL字段的设置,即当前的hard-coded to ^{}。在

请注意,即使考虑到MTIME和XFL的差异,例如使用DEFLATE compression algorithm的不同实现压缩的数据,也可能导致不同的压缩流,即使使用相同的压缩设置!这是因为DEFLATE根据片段的频率对数据进行编码,当压缩时有多个具有相同频率的片段时,不同的实现可以自由地做出不同的选择。因此,测试数据是否被正确压缩的唯一正确方法是再次解压缩并比较结果。

相关问题 更多 >