如何为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实现。 类似地, ListSet具有明确定义的值,前提是它们包含的所有对象具有明确定义的值(请注意,通用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。

  1. 对象 – >字符串(例如,GSON – 您不必编写序列化而不是列出类的所有字段)

  2. String.hashCode() – > int(而不是Object.hashCode()!hashCode()的实现取决于String的内容,而不是内存中的地址—你可以在不同的应用程序启动,不同的线程等中使用它。)

(或2.字符串 – > md5)