5

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

最後の2つのステートメントは、異なる値を返しています。checksum1は、UploadedFileオブジェクトを使用してデータを読み取ることによって生成されます。checksum2は、ファイルシステムから一時ファイルを読み取ることによって生成されます。

ActionDispatch :: Http :: UploadedFileのオブジェクトは、アップロードされたファイルの内容以外のものを返しますか?ファイルシステムに書き込まれたアップロードファイルのチェックサムを生成すると、 (UploadedFile.read)checksum2ではなく(一時ファイルチェックサム)と一致します。checksum1

オブジェクト(UploadedFile)の実装が変更される可能性があるため、ファイルシステムから一時ファイルを読み取ることによって生成されるチェックサムの方が信頼性が高いと想定しています。必要に応じて、ファイルシステム上の既存のファイルのチェックサムを生成する方が簡単です。

では、チェックサムの違いの理由は何ですか?どちらがより信頼できるのでしょうか?

ありがとうございました。


更新1:@ pablo-castellazziの提案に従って、Digest :: SHA256.file(upload.path).hexdigestを使用してハッシュを生成しました。このチェックサム3と呼びましょう

このchecksum3はchecksum1と同じですが、checksum2とは異なります。


更新2:@ Arsen7で言及されているように、バイナリモードを使用してファイルを読み取る場合、すべてのチェックサムは等しくなります。

4

2 に答える 2

2

「data1」と「data2」の内容を比較しましたか? それらをファイルに保存して見てみてください。

最初の読み取りを行う前に呼び出したいと思うかもしれませupload.rewindんが、最初に、ファイルから読み取った生データを確認する必要があります。

アップデート:

Windows を使用しているとは言いませんでした。この場合、注意して、いわゆる「バイナリ」モードでファイルを読み取る必要があります。

File.readメソッドを次のように変更します。

data2 = nil
File.open(upload.path, "rb") {|f| data2 = f.read }

(Pablo Castellazzi の使用.path方法の提案を実装)

バイナリ セーフなエディタ (vim など) でファイルを開いて、違いを比較することをお勧めします。ほとんどのデータは同じかもしれませんが、ファイルの 1 つで行末が異なっていることに気付くでしょう。あるいは、他の違いに気付くかもしれません。

Windows の場合、最も一般的な問題はバイナリ モードです。

于 2011-06-21T11:29:27.227 に答える
1

Rails 3.x を使用していると仮定すると、data1 チェックサムは正しいです。data2 コンテンツは次のように読み取る必要があります。

data2 = File.read(upload.path)

upload.tempfile は、一時ファイルへのパスではなく、ファイル オブジェクトを保持するインスタンスです。

関連する実装の詳細は次のとおりです

File.read(File.read) は、ファイルが見つからないか無効なファイル名に関する何らかの例外をスローする必要があるため、これも奇妙です。

于 2011-06-21T11:43:52.623 に答える