我在Ruby on Rails中生成上传图像的校验和(sha256)。
upload = params[:file]
data1 = upload.read
data2 = File.read(upload.tempfile)
checksum1 = Digest::SHA256.hexdigest(data1)
checksum2 = Digest::SHA256.hexdigest(data2)
puts checksum1
puts checksum2
最后两个语句返回不同的值。 checksum1是通过使用UploadedFile对象读取数据生成的。 checksum2是通过从文件系统读取临时文件生成的。
ActionDispatch :: Http :: UploadedFile的对象是否返回上传文件内容以外的内容?当我生成写入文件系统的上传文件的校验和时,它与checksum2
(临时文件校验和)匹配,而不是与checksum1
(UploadedFile.read)匹配。
我假设通过从文件系统读取临时文件生成的校验和更可靠,因为对象(UploadedFile)实现可能会更改。如果需要,可以更容易地在文件系统上生成现有文件的校验和。
那么,校验和差异的原因是什么,哪一个更可靠?
谢谢。
更新1: 根据@ pablo-castellazzi的建议,我使用Digest :: SHA256.file(upload.path).hexdigest生成哈希。我们称之为checksum3
这个checksum3等于checksum1但与checksum2
不同更新2:如果我使用二进制模式读取@ Arsen7所提到的文件,那么所有校验和都是相同的。
答案 0 :(得分:2)
您是否比较过'data1'和'data2'的内容?尝试将它们保存到文件中并查看。
我想,在您第一次阅读之前,您可能需要调用 upload.rewind
,但首先要看一下从文件中读取的原始数据。
<强>更新强>
你没有说你在Windows上。在这种情况下,您应该注意并以所谓的“二进制”模式读取文件。
将File.read
方法更改为以下内容:
data2 = nil
File.open(upload.path, "rb") {|f| data2 = f.read }
(实施Pablo Castellazzi建议使用.path
方法)
我建议您在二进制安全编辑器(例如vim)中打开文件,并比较不同的内容。您可能会注意到,大多数数据可能是相同的,但在其中一个文件中,行结尾不同,或者您可能会发现其他一些差异。
对于Windows,最常见的问题是二进制模式。
答案 1 :(得分:1)
假设您正在使用Rails 3.x data1校验和是正确的。应使用以下内容读取data2内容:
data2 = File.read(upload.path)
upload.tempfile是保存文件对象的实例,而不是临时文件的路径。
Here是相关的实施细节。
这也很奇怪,因为File.read(File.read)应该抛出一些关于找不到文件或文件名无效的异常。