golang crc32 使用什么参数?

What parameters is golang crc32 using?

提问人:Bradley Lauder 提问时间:9/27/2023 最后编辑:Bradley Lauder 更新时间:9/28/2023 访问量:176

问:

我有一个 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相同的结果(如果我反转多边形)。 (字符串“0”的总和显示0x1D62A0AB与 Go 相同)

有人能帮我理解为什么具有这些基本参数的函数不匹配吗?

go 校验和 CRC CRC32

评论

2赞 icza 9/28/2023
你能告诉我你是如何进入你链接的网站的吗?输入 ,选择 CRC32,结果为 ,与 Go 给出的相同。0xC45441EB00xF4DBDF21
0赞 chuckx 9/29/2023
要获得结果,您必须将算法设置为并填充问题中指定的参数。当位宽设置为 32 时,所有十六进制字段的长度必须为 8ndigits(例如 用于 seed 和 xorout)。需要取消选中 refin 和 refout 选项。0xC45441EBCustom00000000
0赞 rcgldr 9/29/2023
有一点帮助是,如果检查不为零,那么 xorout 也是非零。

答:

1赞 chuckx 9/28/2023 #1

使用 https://www.lddgo.net/en/encrypt/crc,以下参数生成与 Go 实现和 https://simplycalc.com/crc32-source.php Javascript 实现匹配的结果:hash/crc32

  • 位宽:32
  • 多项式公式 (HEX):F4ACFB13
  • 初始值(十六进制):FFFFFFFF
  • XOROUT(十六进制):FFFFFFFF
  • REFIN:真
  • REFOUT:真

这回答了最初的问题,“正在使用哪些参数?

如果您愿意考虑替代实现,则可以使用设计为更灵活的实现。请参见 https://github.com/snksoft/crc

请注意,使用 ,您可以通过 func Update(crc uint32, tab *Table, p []byte) uint32 的第一个参数使用替代初始值。否则,参数将被硬编码。请注意,这些硬编码参数在预定义的多项式(即 IEEE、Castagnoli 和 Koopman)之间共享。添加对更多参数的支持看起来并不简单,因为它需要修改二进制封送/取消封送功能,该功能受向后兼容性保证的约束(请参阅 https://pkg.go.dev/hash#Hash 的最后一段)。hash/crc32hash/crc32


下面是一个比较 和 用法的示例:hash/crc32github.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

Go 游乐场

评论

1赞 Bradley Lauder 9/29/2023
完美的答案,谢谢。经过几个小时的实验,我确实认为情况确实如此。但我想发布这个问题以节省其他人的时间。此外,内置包专注于优化 99% 的情况也很有意义。但是有 4 个常用设置,请告诉我们您使用了哪个!我们不需要通过实验来确定它们,也不需要成为CRC专家来从软件包中推断它们。任何新手都希望默认值为 {0s and falses},而不是相反。感谢您的建议,我会检查 snksoft。