我有一个 crc32 多项式:
poly=0xF4ACFB13
seed=0
xorout=0
refin=no
refout=no
check=0x6c9f84a8
我无法获得 golang 内置 crc32 包来给我正确的校验和。
此网站 https://www.lddgo.net/en/encrypt/crc 产生正确的总和。 (字符串“0”的总和应为 0xC45441EB)
这个网站 https://simplycalc.com/crc32-text.php 产生与 go 相同的结果(如果我反转 Poly)。 (字符串“0”的总和显示 0x1D62A0AB 而与 go 相同)
有人可以帮助我理解为什么具有如此基本参数的函数不匹配吗?
使用 https://www.lddgo.net/en/encrypt/crc,以下参数会生成与 Go
hash/crc32
实现和 https://simplycalc.com/crc32- 上的 Javascript 实现相匹配的结果来源.php:
32
F4ACFB13
FFFFFFFF
FFFFFFFF
这回答了最初的问题,“正在使用哪些参数?”
如果您愿意考虑替代实现,您可以使用设计更灵活的实现。请参阅https://github.com/snksoft/crc。
请注意,使用
hash/crc32
,您可以通过 func Update(crc uint32, tab *Table, p []byte) uint32
的第一个参数使用替代初始值。否则,参数将被硬编码。请注意,这些硬编码参数在预定义多项式(即 IEEE、Castagnoli 和 Koopman)之间共享。向 hash/crc32
添加对更多参数的支持看起来并不简单,因为它需要修改二进制编组/解组功能,而这需要向后兼容性保证。
这是一个比较
hash/crc32
和 github.com/snksoft/crc
用法的示例:
package main
import (
"fmt"
"hash/crc32"
"math/bits"
"github.com/snksoft/crc"
)
func crcSnksoft(params *crc.Parameters, input []byte) uint32 {
h := crc.NewHash(params)
h.Update(input)
return h.CRC32()
}
func crcGo(poly uint32, input []byte) uint32 {
reversedPoly := bits.Reverse32(poly)
t := crc32.MakeTable(reversedPoly)
return crc32.Checksum(input, t)
}
func main() {
poly := 0xF4ACFB13
data := []byte("0")
params := &crc.Parameters{
Width: 32,
Polynomial: uint64(poly),
Init: 0x00000000,
ReflectIn: false,
ReflectOut: false,
FinalXor: 0x00000000,
}
mimicGoParams := &crc.Parameters{
Width: 32,
Polynomial: uint64(poly),
Init: 0xFFFFFFFF,
ReflectIn: true,
ReflectOut: true,
FinalXor: 0xFFFFFFFF,
}
fmt.Printf("snksoft/crc: 0x%X\n", crcSnksoft(params, data))
fmt.Printf("snksoft/crc (matching hash/crc32): 0x%X\n", crcSnksoft(mimicGoParams, data))
fmt.Printf("Go standard library (hash/crc32): 0x%X\n", crcGo(uint32(poly), data))
}
输出:
snksoft/crc: 0xC45441EB
snksoft/crc (matching hash/crc32): 0x1D62A0AB
Go standard library (hash/crc32): 0x1D62A0AB