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:
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.