【问题标题】:CRC-32 implementation in java.util.zip.CRC32java.util.zip.CRC32 中的 CRC-32 实现
【发布时间】:2012-01-25 14:07:47
【问题描述】:

Java CRC-32 类中使用了哪种 CRC-32 算法? java doc 没有提供任何细节。使用的多项式和计算的初始值是什么?

【问题讨论】:

    标签: java crc crc32


    【解决方案1】:

    CRC-32 是在 java.util.zip 的包文档中指定的,将在 RFC 1952 中指定。 RFC 1952 定义了 ISO 3309 中指定的 CRC32,我找不到可以链接到的免费副本。但是 RFC 1952 也指出 ITU-T recommendation V.42 的第 8.1.1.6.2 节指定了相同的实现。

    特别是使用的多项式是

    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
    

    【讨论】:

    • 我使用Java类生成CRC32,但是我需要向不使用java的接收者解释使用的算法。如果我向他提供以下详细信息,我是否正确?符合 ISO/IEC 3309 的 32 位 CRC 算法 使用的多项式为 0x04C11DB7 初始值为 0
    【解决方案2】:

    根据source

    计算数据流的 CRC32 数据校验和。实际的 CRC32 算法在 RFC 1952(GZIP 文件格式规范 4.3 版)。如果使用,可用于通过流获取 CRC32 检查输入/输出流。

    RFC1952 可以在 here 找到,但它提供了相当技术性的阅读。

    CRC 的初始值为0xFFFFFFFF,CRC 表是在类第一次加载到VM 时构建的。

    【讨论】:

    • link 表示初始化值为 0xFFFFFFFF。我很困惑!
    • Dunxton,如果你初始化一个没有内容的新CRC32对象并调用getValue(),它将返回等于00 & 0xffffffffL。不知道这是否是 OP 的意思?
    • 我试过这个link。对于多项式 0x04C11DB7,我将初始值输入为 0,但结果不正确。当我尝试 0XFFFFFFFF 时,我得到了预期值。
    【解决方案3】:

    使用来自 Internet (http://www.sunshine2k.de/coding/javascript/crc/crc_js.html) 的一些工具,我发现 CRC32 参数的组合与从 Java 获得的结果相同:

    • 反映输入,反映结果。
    • 多项式:0x04C11DB7。
    • 初始值:0xFFFFFFFF。
    • 最终异或:0xFFFFFFFF

    【讨论】:

      【解决方案4】:

      currently accepted answer 不正确。

      Java 的 CRC32 类的初始值为 0,而不是 0xFFFFFFFF,从复位函数的源代码中可以看出:

      /**
       * Resets CRC-32 to initial value.
       */
      public void reset() {
          crc = 0;
      }
      

      https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/zip/CRC32.java#L81

      我做了一个快速的蛮力搜索,结果发现用值0xFFFFFFFF 更新 CRC 实际上会产生相同的值。因此,如果您希望 CRC32 算法具有初始值 0XFFFFFFFF,只需执行以下操作:

          CRC32 crc = new CRC32();
          // Set the initial value to 0xFFFFFFFF
          crc.update(new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
      
          System.out.println("CRC: " + crc.getValue());  // prints 4294967295, which is 0xFFFFFFFF
      

      【讨论】:

      • 您正在查看的是一个实现细节。 CRC32 被定义为输出一个补码。因此,new CRC32().getValue() == 0 是初始值0xFFFFFFFF 的预期结果(因为~0xFFFFFFFF == 0)。该实现可能只是采用捷径来计算补码中的所有内容,因此输出不必做任何事情。这也是为什么reset() 设置crc = 0 而不是crc = 0xFFFFFFFF
      猜你喜欢
      • 2011-06-30
      • 2014-10-23
      • 2016-11-06
      • 2011-06-30
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      相关资源
      最近更新 更多