[英]Getting different results while computing md5 for Serializable object vs string
我想计算任何Serilizable对象的md5,这是通过以下函数完成的。
public static String getMd5Hash(Serializable object) {
try {
return getChecksum(object, "MD5");
} catch (Exception e) {
throw new RmsException("Exception while generating md5 hash", e);
}
}
public static String getMd5Hash(Serializable object) {
try {
return getChecksum(object, "MD5");
} catch (Exception e) {
throw new RuntimeException("Exception while generating md5 hash", e);
}
}
private static String getChecksum(Serializable object, String algorithm)
throws IOException, NoSuchAlgorithmException {
try (
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)
) {
oos.writeObject(object);
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] theDigest = md.digest(baos.toByteArray());
return DatatypeConverter.printHexBinary(theDigest);
}
}
测试
@Test
public void getMd5Hash() {
String actual = CryptoUtils.getMd5Hash("water");
Assert.assertEquals("9460370bb0ca1c98a779b1bcc6861c2c", actual);
}
OP
Expected :9460370bb0ca1c98a779b1bcc6861c2c (actual md5 for string water)
Actual :37F7DBD142DABF05ACAA6759C4D9E96C (Why the diff?)
ObjectOutputStream
添加一个标头,因此当您获取字节数组时,您传递的Serializable
实际上并不表示“水”。 打印出baos.toString()
进行验证。 您可以扩展ObjectOutputStream
并重写writeStreamHeader
方法,也md.digest
使用数据的子字符串(即md.digest(baos.substring(7).getBytes())
(或其附近))调用md.digest
。 一旦提取的实际数据是“水”,则哈希将是正确的。
正如特耶所说
ObjectOutPutStream添加一个标头,可以验证使用
public static String getChecksum(Serializable object, String algorithm)
throws IOException, NoSuchAlgorithmException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(object);
oos.flush();
MessageDigest md = MessageDigest.getInstance(algorithm);
md.update(object.toString().getBytes());
byte[] theDigest = md.digest();
System.out.println("Without Object output stream="+DatatypeConverter.printHexBinary(theDigest));
md.reset();
System.out.println("object="+object+ " Written to ByteArray is="+baos.toString());
md.update(baos.toByteArray());
theDigest = md.digest();
return DatatypeConverter.printHexBinary(theDigest);
}
}
public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
System.out.println(getChecksum("water", "MD5"));
}
您可以简单地使用而不是创建所有ByteArrayOutputStream和ObjectOutputStream
md.update(object.toString().getBytes());
将字节数组写入MessageDigest。
谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.