Search code examples
javasecuritygochecksumcrc32

Different CRC32 values in Java and Go


I'm in the process of writing a utility in Go which can be used to calculate CRC32 checksum of an input string. A similar utility exists in Java which we are using extensively and has been working well for us.

The Java Utility uses java.util.zip.CRC32 to calculate the checksum. Pseudo code is as follows :

 public static void main(String[] args) {
        final Checksum checksum = new CRC32();
        byte[] input1Bytes = "input1".getBytes(StandardCharsets.UTF_8);
        checksum.update(input1Bytes, 0, input1Bytes.length);
        final byte[] input2Bytes = "input2".getBytes(StandardCharsets.UTF_8);
        checksum.update(input2Bytes, 0, input2Bytes.length);
        final byte[] input3Bytes = "input3".getBytes(StandardCharsets.UTF_8);
        checksum.update(input3Bytes, 0, input3Bytes.length);
        System.out.println("Checksum in Java : " + checksum.getValue());
    }

The utility in Go uses the crc32 from the hash package of the Go SDK (version 1.13.6) (import "hash/crc32") Pseudo code for generating the checksum in Go is as follows :

    table := crc32.MakeTable(0)
    checksum := crc32.Checksum([]byte("input1"), table)
    checksum = crc32.Update(checksum, table, []byte("input2"))
    checksum = crc32.Update(checksum, table, []byte("input3"))
    log.Printf("Checksum in go : %v", checksum)

The output from the Java code is :

Checksum in Java : 2705255531

The output from the Go code is :

Checksum in go : 4294967295

I've also compared the byte arrays being generated in the 3 steps and they have the same values.

What am i missing and how do I ensure this mismatch is handled?

Appreciate the help!


Solution

  • Use the same polynomial as your Java code, and you get the same results.

    The most common CRC-32 polynomial is there in the crc32 package as a constant: crc32.IEEE = 0xedb88320:

    table := crc32.MakeTable(crc32.IEEE)
    

    With this change you get the same result. Try it on the Go Playground.