我正在寻找一种解决方案来为任何类型的Java对象生成校验和,对于生成相同对象的应用程序的每次执行,它都保持不变。
我用Object.hashCode()
尝试过,但api说
....从应用程序的一次执行到同一应用程序的另一次执行,这个整数不需要保持一致。
答案 0 :(得分:13)
public static String getChecksum(Serializable object) throws IOException, NoSuchAlgorithmException {
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(baos.toByteArray());
return DatatypeConverter.printHexBinary(thedigest);
} finally {
oos.close();
baos.close();
}
}
答案 1 :(得分:9)
我有类似的问题(为XML文件生成好的哈希码),我发现最好的解决方案是使用MD5到MessageDigest,或者如果你需要更快的东西:Fast MD5。请注意,即使Object.hashCode
每次都太短(仅32位)以确保高唯一性,它也是相同的。我认为64位是计算良好哈希码的最小值。请注意,MD5生成128位长的哈希码,在这种情况下应该更多。
当然要使用MessageDigest
,你需要首先序列化(在你的情况下是马歇尔)对象。
答案 2 :(得分:8)
实施例
private BigInteger checksum(Object obj) throws IOException, NoSuchAlgorithmException { if (obj == null) { return BigInteger.ZERO; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); oos.close(); MessageDigest m = MessageDigest.getInstance("SHA1"); m.update(baos.toByteArray()); return new BigInteger(1, m.digest()); }
答案 3 :(得分:5)
我认为你应该看看serialization。序列化机制需要解决类似的问题,因此您可以了解它是如何实现的。
但如果你描述了你试图解决的问题,你可能会得到更精确的解决方案。
答案 4 :(得分:4)
如果您控制源,您可以实现hashCode(),以便从一次执行到另一次执行保持一致。
答案 5 :(得分:3)
您是否希望能够为所有 Java对象执行此操作?
在这种情况下hashCode()
不起作用。
对于某些类hashCode()
有一个更严格的定义,可以保证执行过程中的平等。例如,String
具有明确定义的hashCode
实现。同样地,List
和Set
具有明确定义的值,前提是它们包含的所有对象也具有明确定义的值(请注意,一般Collection.hashCode()
执行不要求定义明确的值。
对于其他类,您必须使用一些明确定义的公式递归地使用反射来构建校验和。
答案 6 :(得分:2)
Hashcode没问题。给定的类覆盖equals
以及合同要求hashcode
。按合同,如果equals
返回true
,则哈希码必须相同
或者类不会覆盖equals
。在这种情况下,应用程序的不同执行不能生成相同的对象,因此没有问题
唯一的问题是某些类(甚至来自Java API)违反了equals
的合同。
答案 7 :(得分:2)
Apache commons lang库提供了一个HashCodeBuilder
类,它有助于构建一个散列代码,满足您对类属性的要求。
示例:
public int checksum() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(17, 37).
append(property1).
append(property2).
append(property3).
toHashCode();
}
答案 8 :(得分:2)
如果你正在使用Eclipse IDE,那么它有动作(在Source菜单下)来生成hashcode和equals函数。它允许您在哈希码中选择所需类的属性。这类似于使用已经建议的HashCodeBuilder方法。
或者,您可以将对象流式传输到字节数组并生成MD5。
答案 9 :(得分:1)
/*
* Calculate checksum of a File using MD5 algorithm
*/
public static String checkSumApacheCommons(Object obj){
String checksum = DigestUtils.md5Hex(String.valueOf(obj));
return checksum;
}
答案 10 :(得分:0)
对象 - >字符串(例如,GSON - 您不必编写序列化而不是列出您班级的所有字段)
String.hashCode() - > int(而不是Object.hashCode()!hashCode()的这种实现取决于String的内容,而不是内存中的地址---你可以在不同的应用程序启动,不同的线程等中使用它。)
< / LI> 醇>(或2. String - &gt; md5)