Ruby Zlib 压缩为相同的输入提供不同的输出

标签 ruby compression gzip zlib

我有这个 ruby​​ 方法来压缩字符串 -

    def compress_data(data)
        output = StringIO.new
        gz = Zlib::GzipWriter.new(output)
        gz.write(data)
        gz.close

        compressed_data = output.string
        compressed_data
    end

当我使用相同的输入调用此方法时,我在不同的时间得到不同的输出。我正在尝试获取压缩输出的字节数组并比较它们。 当我运行以下命令时,输出是不同 -

input = "hello world"

output1 = (compress_data input).bytes.to_a
sleep 1
output2 = (compress_data input).bytes.to_a
if output1 == output2
    puts 'Same'
else
    puts 'Different'
end

当我删除 sleep 时,输出是相同。压缩算法和当前时间有关系吗?

最佳答案

选项 1 - 固定 mtime:

是的。压缩时间存储在 header 中。您可以使用mtime方法将时间设置为固定值,这将解决您的问题:

gz = Zlib::GzipWriter.new(output)
gz.mtime = 1
gz.write(data)
gz.close

请注意the Ruby documentation表示将 mtime 设置为零将禁用时间戳。我尝试了一下,但不起作用。我还查看了源代码,似乎缺少此功能。看起来像一个错误。因此,您必须将其设置为 0 以外的值(但请参阅下面的评论 - 它将在未来的版本中修复)。

选项 2 - 跳过 header :

另一种选择是在检查类似数据时跳过标题。 header 长度为 10 个字节,因此仅检查数据:

data = compress_data(input).bytes[10..-1]

请注意,您不需要在 bytes 上调用 to_a。它已经是一个数组:

String.bytes -> an_array

Returns an array of bytes in str. This is a shorthand for str.each_byte.to_a.

关于Ruby Zlib 压缩为相同的输入提供不同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59050216/

相关文章:

ruby-on-rails - 删除确认轨

javascript - 这段代码在 javascript 中的等价物是什么

linux - 如何使用特定偏移量处的给定 key 通过 XOR 运算符解密二进制文件中的数据?

unix - Tar:创建除一个之外的存档排除目录

c# - C# 和 R 的 Gzip 字节数组不同

ruby - 如何获取哈希中键/值对的位置?

ruby-on-rails - 我如何总结多对多的值(value)?

python - 可以将 python 中的 bz2 解压缩到文件而不是内存

file - 什么是 "[CS Format=A]" header ?

c++ - 我如何在阅读时 "unzip"gzip 流