Rails:上传文件的校验和

时间:2011-06-21 10:45:21

标签: ruby-on-rails windows file-upload checksum sha256

我在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所提到的文件,那么所有校验和都是相同的。

2 个答案:

答案 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)应该抛出一些关于找不到文件或文件名无效的异常。