我正在实现一个程序,将文件分解为git blob并适当地存储它。
我有一个基于git书的文章的ruby参考实现
我正在尝试在这里实施
但是,我遇到了一个问题,即每个实现中存储的压缩数据略有不同。
vbindiff显示前2个字节是相同的(如从该测试脚本运行)(如果我没有看错)。这些字节分别存储压缩方法,标志和标志(根据https://tools.ietf.org/html/rfc1950)。第三个字节是差异开始的地方,这可以是字典ID或原始输入数据的开始。数据将保持相似,直到接近文件末尾。我假设这可能是ADLER32校验和中的差异。
vbindiff
似乎默认情况下,zlib的go和Ruby实现都不会将字典传递给zlib(按照go zlib源代码和ruby zlib源代码)
数据看起来相同。
我不确定库中是否存在实现错误,或者我只是缺少什么。
为什么这些输出不同?
RFC 1951中定义的deflate算法(以RFC 1950定义的zlib格式以及RFC 1952定义的gzip格式使用)允许实现中的变化,这些变化可能导致压缩时产生不同的结果。但是这些结果仍将解压缩为相同的值。这允许在压缩时间到压缩级别之间进行权衡,并使像zopfli这样的程序成为可能,该程序比原始zlib库实现更好的压缩(以明显更长的压缩时间为代价)。
Go使用自己编写的Go语言编写的deflate算法,而ruby使用zlib库。这就是您的示例在同一输入上创建不同的压缩输出的原因。但是,如果您从Go或Ruby程序中获取输出并解压缩(无论是使用Ruby还是Go或任何符合标准的实现),则将再次得到完全相同的值。