Golang tip of the day; PHP-compatible crc32

Submitted by Frederic Marand on

While porting (well, actually rewriting) an old PHP library to Go, I had to use a CRC (cyclic redundancy check) on a buffer. In old-school PHP, the standard is well established since PHP 4: just use crc32 from the strings package, and beware of the sign bit or, to be a bit more current while still compatible, use the hash() function from the hash package, like this example:

= gmp_init(hash("crc32b", $url), 16);
$hex = gmp_strval($hash);

No big deal, Go has a crc32 package, so it should be a direct port, should it not ?

Trouble is, Go went a bit further than PHP (surprise, surprise), and documents its algorithms, unlike PHP just listing them at http://php.net/manual/en/function.hash-algos.php. To wit:

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.
        // http://dx.doi.org/10.1109/26.231911
        Castagnoli = 0x82f63b78

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

But PHP has no reference to the IEEE, Castagnoli, and Koopman polynomials, just listing crc and crc32. A quick check on values gives the expected equivalents.

Language Algorithm Hash of "Hello world"
PHP "crc32" 75883905
"crc32b" 8bd69e52
Go crc32.Castagnoli 72b51f78
crc32.IEEE 8bd69e52
crc32.Koopman b1bcb065

Check with more values to ensure it was not just a collision, and we have a winner: PHP hash('crc32b', $value) is equivalent with Go crc32.ChecksumIEEE(value) . There had to be a reason why this was the only one of the three polynomials to be graced with a dedicated checkum method : neither Castagnoli nor Koopman have one.