Ruby Zlib 压缩为相同的输入提供不同的输出
Ruby Zlib compression gives different outputs for the same input
我有这个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
当我用相同的输入调用这个方法时,我在不同的时间得到不同的输出。我正在尝试获取压缩输出的字节数组并进行比较。
当我 运行 下面的 -
时,输出是 Different
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
当我移除睡眠时,输出是 Same
。压缩算法和当前时间有关系吗?
选项 1 - 固定时间:
是的。压缩时间存储在header中。您可以使用mtime
方法将时间设置为固定值,这将解决您的问题:
gz = Zlib::GzipWriter.new(output)
gz.mtime = 1
gz.write(data)
gz.close
请注意 the Ruby documentation 表示将 mtime
设置为零将禁用时间戳。我试过了,但它不起作用。我也查看了源代码,似乎缺少此功能。似乎是一个错误。所以你必须将它设置为 0 以外的值(但请参阅下面的评论 - 它将在未来的版本中修复)。
选项 2 - 跳过 header:
另一种选择是在检查类似数据时跳过 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压缩字符串的方法-
def compress_data(data)
output = StringIO.new
gz = Zlib::GzipWriter.new(output)
gz.write(data)
gz.close
compressed_data = output.string
compressed_data
end
当我用相同的输入调用这个方法时,我在不同的时间得到不同的输出。我正在尝试获取压缩输出的字节数组并进行比较。 当我 运行 下面的 -
时,输出是Different
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
当我移除睡眠时,输出是 Same
。压缩算法和当前时间有关系吗?
选项 1 - 固定时间:
是的。压缩时间存储在header中。您可以使用mtime
方法将时间设置为固定值,这将解决您的问题:
gz = Zlib::GzipWriter.new(output)
gz.mtime = 1
gz.write(data)
gz.close
请注意 the Ruby documentation 表示将 mtime
设置为零将禁用时间戳。我试过了,但它不起作用。我也查看了源代码,似乎缺少此功能。似乎是一个错误。所以你必须将它设置为 0 以外的值(但请参阅下面的评论 - 它将在未来的版本中修复)。
选项 2 - 跳过 header:
另一种选择是在检查类似数据时跳过 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.