如何为java对象生成校验和

时间:2010-04-15 11:37:52

标签: java object checksum

我正在寻找一种解决方案来为任何类型的Java对象生成校验和,对于生成相同对象的应用程序的每次执行,它都保持不变。

我用Object.hashCode()尝试过,但api说

  

....从应用程序的一次执行到同一应用程序的另一次执行,这个整数不需要保持一致。

11 个答案:

答案 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实现。同样地,ListSet具有明确定义的值,前提是它们包含的所有对象具有明确定义的值(请注意,一般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();
   }

请参阅Commons Lang API

答案 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)

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

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

    < / LI>

    (或2. String - &gt; md5)