如何为java对象生成校验和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2644847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate a checksum for an java object
提问by Alex
I'm looking for a solution to generate a checksum for any type of Java object, which remains the same for every execution of an application that produces the same object.
我正在寻找一种解决方案来为任何类型的 Java 对象生成校验和,对于生成相同对象的应用程序的每次执行都保持相同。
I tried it with Object.hashCode()
, but the api says
我试过了Object.hashCode()
,但api说
....This integer need not remain consistent from one execution of an application to another execution of the same application.
....该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
采纳答案by kopper
I had similar problem (generating good hashcode for XML files) and I found out that the best solution is to use MD5 through MessageDigestor in case you need something faster: Fast MD5. Please notice that even if Object.hashCode
would be the same every time it is anyway too short (only 32 bits) to ensure high uniqueness. I think 64 bits is a minimum to compute good hash code. Please be aware that MD5 generates 128 bits long hash code, which should is even more that needed in this situation.
我遇到了类似的问题(为 XML 文件生成良好的哈希码),我发现最好的解决方案是通过MessageDigest使用 MD5,或者如果您需要更快的东西:Fast MD5。请注意,即使Object.hashCode
每次都相同,它无论如何都太短(只有 32 位)以确保高唯一性。我认为 64 位是计算好的哈希码的最小值。请注意,MD5 生成 128 位长的哈希码,在这种情况下应该更需要。
Of course to use MessageDigest
you need serialize (in your case marshall) the object first.
当然要使用MessageDigest
你需要先序列化(在你的情况下编组)对象。
回答by Roman
I think you should look at serialization. Serialization mechanism needs to solve similar problem, so you can look how it's implemented.
我认为你应该看看序列化。序列化机制需要解决类似的问题,大家可以看看它是如何实现的。
But if you describe the problem you're trying to solve you'll probably get more precise solution.
但是如果你描述了你试图解决的问题,你可能会得到更精确的解决方案。
回答by Seffi
If you control the source, you can implement hashCode() so it will be consistent from one execution to another.
如果您控制源,则可以实现 hashCode() 以使其从一次执行到另一次执行保持一致。
回答by Joachim Sauer
Do you want to be able to do this for allJava objects?
您是否希望能够对所有Java 对象执行此操作?
In that case hashCode()
doesn't work.
在这种情况下hashCode()
不起作用。
For some classes hashCode()
has a stricter definition which guarantees equality across executions. For example String
has a well-defined hashCode
implementation. Similarly List
and Set
have well-defined values, provided all objects that they contain alsohave well-defined values (note that the general Collection.hashCode()
does notrequire the value to be well-defined).
对于某些类hashCode()
具有更严格的定义,以保证执行之间的相等性。例如,String
有一个明确定义的hashCode
实现。同样地List
,并Set
具有明确的价值观,所提供的所有对象,它们包含还具有良好定义的值(注意,一般Collection.hashCode()
不会不要求值是明确定义)。
For other classes you will have to use reflection recursively with some well-defined formula to build a checksum.
对于其他类,您将不得不使用一些定义良好的公式递归地使用反射来构建校验和。
回答by Tadeusz Kopec
Hashcode is OK. Either given class overrides equals
and also, as contract demands, hashcode
. By contract, if equals
returns true
hashcode must be the same.
Or class doesn't override equals
. In this case different executions of your application cannot produce sameobject, so there is no problem.
The only problem is that some classes (even from Java API) break contract for equals
.
哈希码没问题。要么给定类覆盖equals
,要么根据合同要求,hashcode
. 根据约定,如果equals
返回的true
哈希码必须相同。
或者 class 不会覆盖equals
. 在这种情况下,应用程序的不同执行不能产生相同的对象,所以没有问题。
唯一的问题是某些类(甚至来自 Java API)违反了equals
.
回答by FRotthowe
The Apache commons lang library provides a HashCodeBuilder
class which helps building a hash code that fills your requirements from the class properties.
Apache commons lang 库提供了一个HashCodeBuilder
类,该类有助于构建一个哈希码,以满足您对类属性的要求。
Example:
例子:
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();
}
See Commons Lang API
回答by pillingworth
If you're f you're using Eclipse IDE then it has actions (under Source menu) to generate hashcode and equals functions. It allows you to choose the attributes of the class you want in the hashcode. This is similar to using the HashCodeBuilder approach that has already been suggested.
如果您使用的是 Eclipse IDE,那么它有操作(在 Source 菜单下)来生成 hashcode 和 equals 函数。它允许您在哈希码中选择您想要的类的属性。这类似于使用已经建议的 HashCodeBuilder 方法。
Alternatively you could stream the object to a byte array and generate an MD5 of that.
或者,您可以将对象流式传输到字节数组并生成该对象的 MD5。
回答by PeterB
Example
例子
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()); }
回答by Leonardo Leit?o
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();
}
}
回答by Evgeny Nozdrev
Object -> String (For example, GSON - you will not have to write serialization not to list all fields of your class)
String.hashCode() -> int (Instead of Object.hashCode()! This realization of hashCode() depends on content of String, not on address in memory --- you can use it across different app launches, different threads, etc.)
对象 -> 字符串(例如,GSON - 您不必编写序列化来不列出类的所有字段)
String.hashCode() -> int (而不是 Object.hashCode()!hashCode() 的这种实现取决于 String 的内容,而不是内存中的地址 --- 您可以在不同的应用程序启动、不同的线程等中使用它.)
(or 2. String -> md5)
(或 2. 字符串 -> md5)