I need to encode a file such that, if the content of the file is the same, then its encoded version is the same too.
The file I need to encode, config.yml
, contains the following string:
This is my secret setup file
My code is as follows:
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)
At the time when Base64
renders the encoded string, the string must be the exact same if the content of config.yml
is the same. However some metadata seems to be added which makes it impossible to get the same Base64
-encoded string, example:
First run of the script:
H4sICGoAm1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK BQAdlUQpHQAAAA==
Seconds later:
H4sICG4Am1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK BQAdlUQpHQAAAA==
Minutes later:
H4sICGkBm1kAA3VzZXJkYXRhAAvJyCxWAKLcSoXi1OSi1BIgVVJaoJCWmZPK BQAdlUQpHQAAAA==
Your attempt to set mtime
to 0
seems to be ignored. Using an arbitrary value of 1000000000
or even 1
doesn't cause it to shift.
I think this is because the Gzip library is C-based and 0 is considered false, not assigned, and so is overruled.
The Gzip RFC is pretty short and there's not much metadata in there:
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments