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?
2
Answers
That one is the CRC-32/CKSUM:
This CRC shifts up (refin and refout false), whereas the Go hash/crc32 package appears to only support CRC’s that shift down (refin and refout true). You would have to write your own CRC code.
Here is an example in C, which you could translate to Go:
The initial CRC value (returned for
mem == NULL
) is0xffffffff
.Check the parameters for CRC-32/CKSUM on
https://reveng.sourceforge.io/crc-catalogue/all.htm
And compare with the parameters for CRC-32/ISO-HDLC, which I believe corresponds to the algorithm in hash/crc32:
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. A fast/real implementation would create another table from the polynom.