我正在实现一个程序,将文件压缩为 git blob 并适当存储它。
我有一个红宝石参考实现 https://github.com/sgen/git-deflate/blob/bugfix/deflate/deflate-file这是基于git 书中的一篇文章 https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
我正在尝试在 go 中实现这个here https://github.com/sgen/git-deflate/blob/bugfix/deflate/main.go
但是,我遇到了一个问题,即存储的压缩数据与每个实现略有不同。
vbindiff
显示前 2 个字节是相同的(从这个测试脚本 https://github.com/sgen/git-deflate/blob/bugfix/deflate/test-git-deflate)(如果我没看错的话)。这些字节分别存储压缩方法和标志以及标志(根据https://www.rfc-editor.org/rfc/rfc1950 https://www.rfc-editor.org/rfc/rfc1950)。第三个字节是差异开始的地方,它要么是字典 ID,要么是原始输入数据的开始。数据保持相似,直到接近文件末尾。我假设这可能是 ADLER32 校验和的差异。
默认情况下,zlib 的 go 和 Ruby 实现似乎都不会向 zlib 传递字典(根据转到 zlib 源 https://golang.org/src/compress/zlib/reader.go?s=2009:2059#L60 and ruby zlib 源 https://github.com/ruby/zlib/blob/master/ext/zlib/zlib.c#L1622)
数据看起来相同。
我不确定库中是否存在实现错误,或者我是否遗漏了某些内容。
为什么这些输出不同?
RFC 1951 中定义的 deflate 算法(用于 RFC 1950 定义的 zlib 格式以及 RFC 1952 定义的 gzip 中)允许实现中的变化,这可能会在压缩时导致不同的结果。但这些结果仍然会解压缩到相同的值。这允许在压缩时间和压缩级别之间进行权衡,并且还使得像这样的程序zopfli https://github.com/google/zopfli可能实现比原始 zlib 库更好的压缩(以明显更长的压缩时间为代价)。
Go 使用自己的用 Go 编写的 deflate 算法实现,而 ruby 使用zlib库 https://zlib.net/。这就是您的示例在同一输入上创建不同压缩输出的原因。但是,如果您从 Go 或 Ruby 程序中获取输出并再次解压缩(无论是使用 Ruby 还是 Go 或任何符合标准的实现),它都会得到完全相同的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)