相同原始内容生成的两份zlib压缩数据差异原因咨询
zlib压缩数据差异原因分析
以下是你提供的Python代码:
import zlib, json ZLIB_SUFFIX = b'\x00\x00\xff\xff' data = json.dumps({ "t": None, "s": None, "op": 10, "d": { "heartbeat_interval": 41250, "_trace": [ '["gateway-prd-us-east1-b-4kf6",{"micros":0.0}]' ] } }, separators=(',', ':')).encode('utf-8') deflate = zlib.compressobj(6, zlib.DEFLATED, zlib.MAX_WBITS) result = deflate.compress(data) + deflate.flush() + ZLIB_SUFFIX print(result)
核心差异点拆解
对比两份十六进制压缩数据,差异集中在两处:
1. 压缩块的结束标记差异
原始zlib数据第三个字节为34(二进制00110100),Python生成的为35(二进制00110101):
- 这是deflate压缩流的第一个块头部:
- 块头部第一位表示「是否为最后一个块」:
34的第一位是0(当前块不是最后块),35的第一位是1(当前块是最后块) - 两者的块类型都是01(固定哈夫曼编码),其余位对应的块长度参数完全一致
- 块头部第一位表示「是否为最后一个块」:
2. 压缩流的尾部校验差异
原始数据在压缩数据末尾直接追加了0000ffff,而Python生成的流程是:
- 先输出deflate标准结束块的校验数据(
b1bd2815,即原始JSON数据的Adler-32校验和) - 再追加你代码中手动添加的
0000ffff
差异原因解释
关于块结束标记
你的Python代码调用deflate.flush()时使用默认的Z_FINISH模式,会将整个输入的JSON数据压缩为单个结束块(标记为最后一个块)。
而原始数据的压缩逻辑是将数据处理为多块格式(第一个块标记为非最后块),但后续没有实际数据块,直接用0000ffff作为结束标识,属于非标准的deflate实现。
关于尾部校验
标准zlib压缩流的结尾会包含4字节的Adler-32校验和,用于验证解压后数据的完整性。deflate.flush(Z_FINISH)会自动生成并添加这个校验和,但原始数据没有遵循标准,省略了校验和直接使用自定义的0000ffff结尾。
额外说明
你代码中手动添加的ZLIB_SUFFIX = b'\x00\x00\xff\xff'并非标准zlib协议的一部分,这是原始数据使用的自定义结束标记。如果需要生成与原始数据完全一致的结果,需要调整压缩块的生成方式,并省略标准的Adler-32校验和。
内容的提问来源于stack exchange,提问作者Lyar
相关产品推荐
相关产品推荐

