0

我正在使用以下命令从memcached转储给定键的压缩对象:

cat <(printf "\x1f\x8b\x08\x00\x00\x00\x00\x00") <(memccat CACHE-KEY) | gunzip

它打印值(一个 JSON),但最后会出现警告:

gzip:标准输入:文件意外结束

我相信它可能缺少最后 4 个字节的校验和 ( ADLER32),但我不确定。

从Memcached缓存服务以纯文本格式转储压缩键值的正确方法是什么?

4

1 回答 1

1

看起来结果memccat CACHE-KEY是一个 zlib ( RFC 1950 ) 流。您为 gzip 流 ( RFC 1952 ) 提供了 gzip 标头的十个字节中的八个作为前缀,这导致gunzip将两字节 zlib 标头作为 gzip 标头末尾缺少的两个字节吃掉。gunzip然后期待它得到的放气流(RFC 1951),然后是它没有得到的gzip预告片。一个 gzip 尾部是 8 个字节,由 CRC-32 和未压缩数据的长度组成。相反,它正在获取 zlib 预告片,它是未压缩数据的四字节 Adler-32。

要满足 gunzip,您不需要给它 zlib 流的最后四个字节,而是将其替换为八个字节,其中包括您需要计算的未压缩数据的 CRC-32 和未压缩数据的长度. 不过这有点傻,因为这些事情的重点是对未压缩数据进行完整性检查。

您真正想要做的是将该 zlib 流解释为 zlib 流,这将在最后使用 Adler-32 作为完整性检查。您可以使用pigz来解码 zlib 流pigz -dz,或者您可以使用 zlib 轻松编写自己的 zlib 解码在名为zpipe的示例目录中提供了一个示例。

于 2018-03-04T18:52:27.377 回答