0

私の要件は、ローカル ディスク上のファイルとデータベースからダウンロードしたファイルの MD5 ハッシュを比較することです。ファイルは、SQL Server の VARBINARY(MAX) 列に格納されます。ファイルは任意のタイプにすることができます。現在、PDFファイルでテストしています。HttpPost リクエストを使用して、データベースからファイルを取得します。JSONObject は、HttpResponse オブジェクトを使用して構築されます。JSONObject には、ファイルの内容がバイナリ形式で含まれています。

次に、受信したバイナリ データの MD5 ハッシュを、ディスク上の同じファイルの MD5 ハッシュと比較する必要があります。次のコードを書きましたが、MD5 ハッシュが一致しません。ダウンロードしたバイナリ コンテンツの MD5 を単純に計算するのは間違っていると思います。これを行う正しい方法はありますか?前もって感謝します。

// Read response from a HttpResponse object 'response'
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line="";
StringBuilder sb = new StringBuilder();
while((line=reader.readLine())!=null) {
      sb.append(line);
}

// construct jsonobject
JSONObject jsonResponse = new JSONObject(sb.toString());

//Read file from disk
FileInputStream fis = new FileInputStream(new File(this.getClass().getResource("C:\\demo.pdf").getPath()));

// Calculate MD5 of file read from disk
String md5Request = org.apache.commons.codec.digest.DigestUtils.md5Hex(fis);

// Calculate MD5 of binary contents. "binfile" is name of key in the JSONObject 
// and binary contents of downloaded file are in its corresponding value field
String md5Response = org.apache.commons.codec.digest.DigestUtils.md5Hex(jsonResponse.getString("binfile"));

Assert.assertEquals("Hash sums of request and response must match", md5Request, md5Response);

デバッグすると、JSONObject 'jsonResponse' の binfile キーに対してこの値が表示されます

binfile=[37,80,68,70,45,49,46,52,13,37,-30,-29,-49,-45,13,10,52,48...]

その後に続くのは、バイナリ データの長いストリームです。

4

2 に答える 2

1

OK、SQL には次のような組み込み関数があります。

select *, 
convert(varchar(50),master.sys.fn_repl_hash_binary(a.BinaryField),2) as 'MD5Hash'
from SomeTable a

fn_repl_hash_binary には、読み取っているバイナリ フィールドの名前に加えて、値を MD5 として計算するように SQL に指示する引数として "2" を指定します。「1」はSHAだと思います。

Java では、次のようなものを使用できます。

private String getMD5Hash(byte[] bytes) throws java.lang.Exception{
   String s="This is a test";
   MessageDigest m=MessageDigest.getInstance("MD5");
   m.update(bytes,0,bytes.length);
   return new BigInteger(1,m.digest()).toString(16);
}

これでうまくいくはずです。幸運を祈ります、CodeWarrior。

于 2013-06-11T12:05:51.623 に答える
0

これは新しい投稿ではありませんが、Pythonでもこの問題に直面し、方法を見つけるためにたくさんのテストを行ったので、ここに可能な解決策があります...

すべてのデータをバイナリで扱うため、ファイルを開いてバイナリ モードで比較する必要があります。

正しい MD5 チェックサムを読み取るたびに失敗していた元のコード:

    with open(filepath, "r") as file_to_check:
        tile_file = file_to_check.read()

修正されたコード:

    with open(filepath, "rb") as file_to_check:
        tile_file = file_to_check.read()

read (r) フラグの後に b (binary) を追加するだけで、ファイルをバイナリとして読み取る必要があることを python に知らせ、動作するようになりました。

これはあなたの問題を見つけるのに役立つかもしれません...お役に立てば幸いです!

于 2013-10-07T05:08:51.717 に答える