一尘不染

压缩后的输出不同于Go to Ruby的实现

go

我正在实现一个程序,将文件分解为git blob并适当地存储它。

我有一个基于git书的文章ruby参考实现

我正在尝试在这里实施

但是,我遇到了一个问题,即每个实现中存储的压缩数据略有不同。

vbindiff显示前2个字节是相同的(如从该测试脚本运行)(如果我没有看错)。这些字节分别存储压缩方法,标志和标志(根据https://tools.ietf.org/html/rfc1950)。第三个字节是差异开始的地方,这可以是字典ID或原始输入数据的开始。数据将保持相似,直到接近文件末尾。我假设这可能是ADLER32校验和中的差异。

似乎默认情况下,zlib的go和Ruby实现都不会将字典传递给zlib(按照go
zlib源代码
ruby
zlib源代码

数据看起来相同。

我不确定库中是否存在实现错误,或者我只是缺少什么。

为什么这些输出不同?


阅读 176

收藏
2020-07-02

共1个答案

一尘不染

RFC 1951中定义的deflate算法(以RFC 1950定义的zlib格式以及RFC
1952定义的gzip格式使用)允许实现中的变化,这些变化可能导致压缩时产生不同的结果。但是这些结果仍将解压缩为相同的值。这允许在压缩时间到压缩级别之间进行权衡,并使像zopfli这样的程序成为可能,该程序比原始zlib库实现更好的压缩(以明显更长的压缩时间为代价)。

Go使用自己编写的Go语言编写的deflate算法,而ruby使用zlib库。这就是您的示例在同一输入上创建不同的压缩输出的原因。但是,如果您从Go或Ruby程序中获取输出并解压缩(无论是使用Ruby还是Go或任何符合标准的实现),则将再次得到完全相同的值。

2020-07-02