How do I create a checksum (MD5, sha512, whatever) of a file when I upload it, so that when I download (using cache_stored_file!
), I can verify that it is indeed the original file that was uploaded?

- 731
- 1
- 17
- 34
-
Possible duplicate of http://stackoverflow.com/questions/34490/how-do-i-create-a-sha1-hash-in-ruby ? – Jake Worth Jul 20 '15 at 20:06
-
@JakeWorth No, that's a part of it, but I'm specifically looking to have carrierwave get the hash of the file, store it, and then use it to verify the download when used to do post-processing on the file. – jrg Jul 20 '15 at 20:16
2 Answers
The Ruby Digest module can help with this.
One way solution would be to read the file on upload and assign it a unique digest with a before_create
callback. I would add it as a column on the file table in your database.
Here's some output from IRB to show how it would work:
2.2.2 :001 > require 'digest'
=> true
2.2.2 :002 > f = File.read 'test.rb'
=> "Original content\n"
2.2.2 :003 > Digest::SHA256.hexdigest(f)
=> "646722e7ee99e28d618142b9d3a1bfcbe2196d8332ae632cc867ae5d1c8c57b5"
# (... file modified ...)
2.2.2 :004 > f = File.read 'test.rb'
=> "Original content with more content\n"
2.2.2 :005 > Digest::SHA256.hexdigest(f)
=> "c29f2f77c0777a78dbdf119bf0a58b470c098635dfc8279542e4c49d6f20e62c"
You can use this digest in your download method to check the integrity of the file. If you read the file again, produce a digest, and it matches the original digest, you can be confident the file hasn't been altered since it was uploaded.

- 5,490
- 1
- 25
- 35
md5 = Digest::MD5.file('path_to_file').hexdigest
This would read file in blocks and avoid reading the whole file in RAM which is done in File.read()
For SHA checksum
Digest::SHA2.hexdigest( File.read("/path/to/my/file.txt") );
OR
Digest::SHA2.file(myFile).hexdigest
=> "fa5880ac744f3c05c649a864739530ac387c8c8b0231a7d008c27f0f6a2753c7"
More details for SHA checksum generation SHA Checksum

- 12,577
- 2
- 23
- 24