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.