Tip of the day: PHP-compatible CRC32

Fragment of a CRC algorithm diagram
Image credits: Zhu Han

PHP includes crc32() and hash("crc32") functions.

Do they have an exact counterpart in the Go runtime library ?

The actual issue

While porting (ok, rewriting) an old PHP library in Go, I had to compute a CRC (cyclic redundancy check) checksum. In traditional PHP, the standard function for this has been present since PHP4 : just use the crc32 function, included in the strings library, and check the sign bit. For more modern code with identical results, use the hash function found in the hash, library, as in this example :

1
2
3
4
<?php
    $hash = gmp_init(hash("crc32b", $url), 16);
    $hex = gmp_strval($hash);
?>

No problem in sight : the Go runtime library includes a paquet hash/crc32 package, so all should port smoothly, should it not ?

There is just a small problem ; unlike PHP just listing the names of of its CRC algorithms on the hash_algos function page, the Go runtime library goes one step further (are you surprised yet ?) and actually documents the ones it implements, like this

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const (
        // IEEE is by far and away the most common CRC-32 polynomial.
        // Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
        IEEE = 0xedb88320

        // Castagnoli's polynomial, used in iSCSI.
        // Has better error detection characteristics than IEEE.
        // https://dx.doi.org/10.1109/26.231911
        Castagnoli = 0x82f63b78

        // Koopman's polynomial.
        // Also has better error detection characteristics than IEEE.
        // https://dx.doi.org/10.1109/DSN.2002.1028931
        Koopman = 0xeb31d82e
)

Now, PHP contains no reference to the IEEE, Castagnoli, or Koopman polynomials, just listing crc and crc32 as a description.

The answer

Computing the values for each variation allows one to identify which polynomial actually matches :

LanguageAlgorithmCRC of Hello world
PHPcrc3275883905
PHPcrc32b8bd69e52
Gocrc32.Castagnoli72b51f78
Gocrc32.IEEE8bd69e52
Gocrc32.Koopmanb1bcb065

After summing a bunch of other values to ensure this was not just a chance hit, we have the expected result:

  • PHP hash(‘crc32b’, $value)
  • is equivalent to Go crc32.ChecksumIEEE(value).