Ruby - 阻止GzipWriter将元数据添加到其标题

时间:2017-08-21 15:53:11

标签: ruby gzip

我需要编码一个文件,如果文件的内容相同,那么它的编码版本也是一样的。

我需要编码的文件config.yml包含以下字符串:

This is my secret setup file

我的代码如下:

require 'stringio'
require 'base64'
require 'zlib'

my_text = File.read('config.yml')
wio = StringIO.new('W')
w_gz = Zlib::GzipWriter.new(wio)
w_gz.mtime = 0 # Specify the modification time (mtime) in the gzip header
w_gz.orig_name = 'userdata' # Specify the original name (str) in the gzip header
w_gz.write(my_text)
w_gz.close
puts Base64.encode64(wio.string)

Base64呈现编码字符串时,如果config.yml的内容相同,则字符串必须完全相同。但是,似乎添加了一些元数据,这使得无法获得相同的Base64编码字符串,例如:

首次运行脚本:

  

H4sIC的开始 Am1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK   BQAdlUQpHQAAAA ==

秒后:

  

H4sIC的 G4 Am1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK   BQAdlUQpHQAAAA ==

几分钟后:

  

H4sIC的 GKB m1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK   BQAdlUQpHQAAAA ==

2 个答案:

答案 0 :(得分:2)

您将mtime设置为0的尝试似乎被忽略了。使用10000000001的任意值不会导致它移位。

我认为这是因为Gzip库是基于C的,0被认为是假的,没有分配,所以被否决了。

Gzip RFC很短,而且那里的元数据不多:

 +---+---+---+---+---+---+---+---+---+---+
 |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
 +---+---+---+---+---+---+---+---+---+---+

答案 1 :(得分:0)

只需用零替换手动替换压缩结果的第5到第8个字节(索引4..7)。这将mtime设置为零,表示每个RFC没有设置时间。似乎没有办法让Ruby的课程为你做这件事。