如何为java对象生成校验和
我正在寻找一种解决方案来为任何类型的Java对象生成校验和,对于生成相同对象的应用程序的每次执行,它都保持不变。
我用Object.hashCode()
尝试过,但api说
….从应用程序的一次执行到同一应用程序的另一次执行,这个整数不需要保持一致。
我有类似的问题(为XML文件生成良好的哈希码),我发现最好的解决方案是通过MessageDigest使用MD5,或者如果你需要更快的东西: 快速MD5 。 请注意,即使Object.hashCode
每次都太短(只有32位)都是相同的,以确保高唯一性。 我认为64位是计算良好哈希码的最小值。 请注意,MD5生成128位长的哈希码,在这种情况下应该更加需要。
当然要使用MessageDigest
您需要首先序列化(在您的情况下是marshall)对象。
例
private BigInteger checksum(Object obj)抛出IOException,NoSuchAlgorithmException { if(obj == null){ 返回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()); 返回new BigInteger(1,m.digest()); }
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(); } }
我想你应该看一下序列化 。 序列化机制需要解决类似的问题,因此您可以查看它是如何实现的。
但如果你描述了你试图解决的问题,你可能会得到更精确的解决方案。
如果您控制源,则可以实现hashCode(),以便从一个执行到另一个执行保持一致。
您是否希望能够为所有 Java对象执行此操作?
在这种情况下, hashCode()
不起作用。
对于某些类, hashCode()
具有更严格的定义,可以保证执行过程中的相等性。 例如, String
有一个定义良好的hashCode
实现。 类似地, List
和Set
具有明确定义的值,前提是它们包含的所有对象也具有明确定义的值(请注意,通用Collection.hashCode()
不需要对值进行明确定义)。
对于其他类,您必须使用一些明确定义的公式递归地使用reflection来构建校验和。
Hashcode没问题。 给定的类覆盖equals
并且,作为契约要求, hashcode
。 通过契约,如果equals
返回true
,则hashcode必须相同。
或者类不会覆盖equals
。 在这种情况下,应用程序的不同执行不能生成相同的对象,因此没有问题。
唯一的问题是某些类(甚至来自Java API)违反了equals
合同。
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(); }
请参阅Commons Lang API
如果你正在使用Eclipse IDE,那么它有动作(在Source菜单下)来生成hashcode和equals函数。 它允许您在哈希码中选择所需类的属性。 这类似于使用已经建议的HashCodeBuilder方法。
或者,您可以将对象流式传输到字节数组并生成MD5。
-
对象 – >字符串(例如,GSON – 您不必编写序列化而不是列出类的所有字段)
-
String.hashCode() – > int(而不是Object.hashCode()!hashCode()的实现取决于String的内容,而不是内存中的地址—你可以在不同的应用程序启动,不同的线程等中使用它。)
(或2.字符串 – > md5)