【问题标题】:How to generate a checksum for an java object如何为 java 对象生成校验和
【发布时间】:2011-02-08 08:18:48
【问题描述】:

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

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

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

【问题讨论】:

  • 能否添加报价链接?
  • int checksum(Object o) { return 1;} 满足您的要求 :-)
  • 更详细地说,我必须检查两个应用程序调用之间的对象(编组的 xml 请求)是否相同。
  • @Alex:那你为什么不比较原始 XML 的相等性呢?这可能比您尝试的要容易得多(即使您让它容忍空格的变化或类似的细微差异)。

标签: java object checksum


【解决方案1】:
/*
 * Calculate checksum of a File using MD5 algorithm
 */
public static String checkSumApacheCommons(Object obj){
    String checksum = DigestUtils.md5Hex(String.valueOf(obj));
    return checksum;
}

【讨论】:

    【解决方案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

    【讨论】:

      【解决方案3】:
      1. 对象 -> 字符串(例如,GSON - 您不必编写序列化来列出类的所有字段)

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

      (或 2. 字符串 -> md5)

      【讨论】:

        【解决方案4】:
        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();
            }
        }
        

        【讨论】:

          【解决方案5】:

          例子

          私有 BigInteger 校验和(对象 obj)抛出 IOException,NoSuchAlgorithmException { 如果(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()); 返回新的 BigInteger(1, m.digest()); }

          【讨论】:

            【解决方案6】:

            如果您使用的是 Eclipse IDE,那么它有一些动作(在 Source 菜单下)来生成 hashcode 和 equals 函数。它允许您在哈希码中选择您想要的类的属性。这类似于使用已经建议的 HashCodeBuilder 方法。

            或者,您可以将对象流式传输到字节数组并生成其 MD5。

            【讨论】:

              【解决方案7】:

              我遇到了类似的问题(为 XML 文件生成良好的哈希码),我发现最好的解决方案是通过 MessageDigest 使用 MD5,或者如果您需要更快的东西:Fast MD5。请注意,即使Object.hashCode 每次都相同,但无论如何它太短(只有 32 位)以确保高唯一性。我认为 64 位是计算良好哈希码的最低要求。请注意,MD5 会生成 128 位长的哈希码,在这种情况下应该会更多。

              当然要使用MessageDigest,您需要先序列化(在您的情况下编组)对象。

              【讨论】:

              • 谢谢大家的回答。我从编组的请求中计算出 MD5。
              【解决方案8】:

              哈希码没问题。任何一个给定的类都会覆盖equals,并且根据合同要求,hashcode。按照约定,如果equals 返回true,哈希码必须相同。
              或者类不会覆盖equals。在这种情况下,您的应用程序的不同执行不能产生相同的对象,所以没有问题。
              唯一的问题是某些类(甚至来自 Java API)违反了equals 的约定。

              【讨论】:

                【解决方案9】:

                您希望能够为 所有 Java 对象执行此操作吗?

                在这种情况下hashCode() 不起作用。

                对于某些类hashCode() 具有更严格的定义,以保证执行之间的平等。例如String 有一个明确定义的hashCode 实现。类似地,ListSet 具有明确定义的值,前提是它们包含的所有对象具有明确定义的值(请注意,一般的 Collection.hashCode() 确实需要明确定义的值)。

                对于其他类,您将不得不通过一些定义明确的公式递归地使用反射来构建校验和。

                【讨论】:

                  【解决方案10】:

                  如果你控制了源,你可以实现 hashCode() 这样它在一次执行到另一次执行时是一致的。

                  【讨论】:

                    【解决方案11】:

                    我认为你应该看看serialization。序列化机制需要解决类似的问题,所以你可以看看它是如何实现的。

                    但如果你描述你试图解决的问题,你可能会得到更精确的解决方案。

                    【讨论】:

                      猜你喜欢
                      • 2014-09-15
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-03-13
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-03-19
                      • 1970-01-01
                      • 2012-10-20
                      相关资源
                      最近更新 更多