I have the following inside a unit test to try and figure out why my DigestOutputStream
is not calculating the correct digest for a test .jpg
I have in the classpath.
The assertArrayEquals()
passes but the final assertEquals()
fails with different results.
// the .jpg is 32394 bytes
final MessageDigest md5 = MessageDigest.getInstance("md5");
md5.update(ByteStreams.toByteArray(getInputStream()));
final String h0 = DatatypeConverter.printHexBinary(md5.digest());
System.out.println("MD5 = " + h0); // MD5 = 98BE96C5B9C8D0E41723BBA6E508AADC
// raw MessageDigest from InputStream to ByteArrayOutputStream
final MessageDigest md5a = MessageDigest.getInstance("md5");
final ByteArrayOutputStream baosa = new ByteArrayOutputStream(32394);
ByteStreams.copy(getInputStream(), baosa);
md5a.update(baosa.toByteArray());
final String ha = DatatypeConverter.printHexBinary(md5a.digest());
assertArrayEquals(ByteStreams.toByteArray(getInputStream()),baosa.toByteArray());
assertEquals(h0,ha);
// raw DigestOutputStream to ByteArrayOutputStream
final ByteArrayOutputStream baosb = new ByteArrayOutputStream(32394);
final DigestOutputStream dos = new DigestOutputStream(baosb, MessageDigest.getInstance("md5"));
ByteStreams.copy(getInputStream(), dos);
final String hb = DatatypeConverter.printHexBinary(dos.getMessageDigest().digest());
assertArrayEquals(baosa.toByteArray(), baosb.toByteArray());
assertEquals(h0,hb); // <-- this is where it fails
Failure:
MD5 = 98BE96C5B9C8D0E41723BBA6E508AADC
org.junit.ComparisonFailure:
Expected :98BE96C5B9C8D0E41723BBA6E508AADC
Actual :D41D8CD98F00B204E9800998ECF8427E
And for completeness here is what I am reading in for each of the cases:
private InputStream getInputStream()
{
return Thread.currentThread().getContextClassLoader().getResourceAsStream("Al_Bundy_Shoot_Me_$12.jpg");
}
Here is the image I am reading in off the classpath in all cases:
I needed to close the DigestOutputStream
before trying to get the .digest()
off of it.
final DigestOutputStream dos = new DigestOutputStream(baosb, MessageDigest.getInstance("md5"));
ByteStreams.copy(getInputStream(), dos);
dos.close(); // <-- this fixed the problem!
final String hb = DatatypeConverter.printHexBinary(dos.getMessageDigest().digest());
Apparently .flush()
makes it behave correctly as well.