Question

Which CRC-32 algorithm is used in the Java CRC-32 class ? The java doc does not give any details. What is the polynomail used and the initial value for calculaton ?

Was it helpful?

Solution

According to the source:

Computes CRC32 data checksum of a data stream. The actual CRC32 algorithm is described in RFC 1952 (GZIP file format specification version 4.3). Can be used to get the CRC32 over a stream if used with checked input/output streams.

The RFC1952 can be found here, but presents a quite technical read.

The initial value for the CRC is 0xFFFFFFFF, and the CRC table is built the first time the class is loaded on the VM.

OTHER TIPS

CRC-32 is a indicated in the package docs for java.util.zip to be specified in RFC 1952. RFC 1952 defines CRC32 as specified in ISO 3309 which I could not find a free copy of to link you to. However RFC 1952 also indicates that section 8.1.1.6.2 of ITU-T recommendation V.42 specifies the same implementation.

In partcular the polynomial being used is

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

Using some tools from Internet ( http://www.sunshine2k.de/coding/javascript/crc/crc_js.html ) I've found a combination of CRC32 parameters that gives the same results as obtained from Java:

  • Input reflected, result reflected.
  • Polynomial: 0x04C11DB7.
  • Initial value: 0xFFFFFFFF.
  • Final XOR: 0xFFFFFFFF

The currently accepted answer is incorrect.

The initial value for Java's CRC32 class is 0, not 0xFFFFFFFF, as can be seen in the source code for the reset function:

/**
 * 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

I did a quick brute-force search, and it turns out that updating the CRC with the value 0xFFFFFFFF will actually yield that same value. So if you'd like the CRC32 algorithm to have the initial value 0XFFFFFFFF, just do:

    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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top