I took the source code of cksum
and copied the polynomial. This gives the same as the predefined IEEE variant defined in the Go standard library.
package main
import (
"fmt"
"hash/crc32"
)
// https://github.com/coreutils/coreutils/blob/a9b78541fa7c06567c5b82fb4e89d85a1dc0c611/src/cksum.c#L54
//
// 32 26 23 22 16 12 11 10 8 7 5 4 2 1
// G(X)=X + X + X + X + X + X + X + X + X + X + X + X + X + X + 1
const p = 0b11101101101110001000001100100000
func main() {
cksum := crc32.MakeTable(p)
fmt.Println(crc32.Checksum([]byte("moin"), cksum))
fmt.Println(crc32.ChecksumIEEE([]byte("moin")))
}
The result is: 3048661102
But when I use the cksum
on Debian 12 (coreutils 9.1) the result is something else:
$ printf "moin" | cksum
1401816862 4
What is wrong here?
Update
I think the problem is explained here.
But the question is still: How to do with "hash/crc32" the same as cksum
does?
Check the parameters for CRC-32/CKSUM on https://reveng.sourceforge.io/crc-catalogue/all.htm
width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b name="CRC-32/CKSUM"
And compare with the parameters for CRC-32/ISO-HDLC, which I believe corresponds to the algorithm in hash/crc32:
width=32 poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926 residue=0xdebb20e3 name="CRC-32/ISO-HDLC"
It is only possible to adjust poly (the polynom) in hash/crc32, but not init (initial value), refin (reflected input) or refout (reflected output).
In addition to these parameters, the cksum program also processes a representation of the input stream length following the input.
Here is some naive code that produces the expected output with hash/crc32. A fast/real implementation would create another table from the polynom.