0

My requirement is to compare the MD5 hashes of a file on the local disk and a file downloaded from a database. The file is stored on SQL Server in a VARBINARY(MAX) column. The file can be any type. I'm currently testing with a PDF file. I get the file from the database using a HttpPost request. A JSONObject is built using the HttpResponse object. The JSONObject contains the file contents in binary format.

Now I have to compare the MD5 hash of the received binary data against the MD5 hash of the same file on disk. I have written the following code but the MD5 hashes do not match. I think I'm going wrong in simply calculating the MD5 of the downloaded binary contents. Is there a correct way to do this? Thanks in advance.

// 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);

When I debug, I see this value against the binfile key in the JSONObject 'jsonResponse'

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

and what follows is a lengthy stream of binary data.

4

2 回答 2

1

好的,在 SQL 中有一个如下所示的内置函数:

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

你给 fn_repl_hash_binary 你正在读取的二进制字段的名称,加上“2”作为参数,告诉 SQL 将值计算为 MD5;我认为“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 (二进制),让 python 知道它需要以二进制形式读取文件,现在它可以工作了。

这可能会帮助你找到你的问题......希望它有帮助!

于 2013-10-07T05:08:51.717 回答