Java和Go中的CRC32值不同

3

我正在使用Go语言编写一个实用程序,可用于计算输入字符串的CRC32校验和。我们广泛使用Java中的类似实用程序,并且一直为我们工作良好。

Java实用程序使用java.util.zip.CRC32来计算校验和。伪代码如下:

 public static void main(String[] args) {
        final Checksum checksum = new CRC32();
        byte[] input1Bytes = "input1".getBytes(StandardCharsets.UTF_8);
        checksum.update(input1Bytes, 0, input1Bytes.length);
        final byte[] input2Bytes = "input2".getBytes(StandardCharsets.UTF_8);
        checksum.update(input2Bytes, 0, input2Bytes.length);
        final byte[] input3Bytes = "input3".getBytes(StandardCharsets.UTF_8);
        checksum.update(input3Bytes, 0, input3Bytes.length);
        System.out.println("Checksum in Java : " + checksum.getValue());
    }

该 Go 语言实用程序使用 Go SDK(版本1.13.6)的 hash 包中的 crc32import "hash/crc32")。

生成 Go 中校验和的伪代码如下:

    table := crc32.MakeTable(0)
    checksum := crc32.Checksum([]byte("input1"), table)
    checksum = crc32.Update(checksum, table, []byte("input2"))
    checksum = crc32.Update(checksum, table, []byte("input3"))
    log.Printf("Checksum in go : %v", checksum)

Java代码的输出为:
Checksum in Java : 2705255531

Go代码的输出是:
Checksum in go : 4294967295

我还比较了在这3个步骤中生成的字节数组,它们具有相同的值。

我错过了什么?如何确保处理此不匹配情况?

感谢您的帮助!


不是4294967295等于0xFFFF_FFFF吗?那么Golang似乎有问题。 - Joop Eggen
4
crc32.MakeTable(0) 这个调用明显是错误的:你将多项式设置为了零。你想要哪个多项式?(零永远不正确。)请参见 https://dev59.com/9V_Va4cB1Zd3GeqPVqxM - torek
非常感谢@JoopEggen和@torek的回复。你是对的@torek,crc32.MakeTable(0)是问题所在。我将其更改为table := crc32.IEEETable,看起来它正在工作。将在此上运行测试以确保它涵盖了所有方面。 - saarthak gupta
1
是的,看起来那就是正确的代码。请注意,hash/crc32 代码使用了小端(或位反转)多项式,因此 0x04C11DB7 是不正确的。然而,将 0x04C11DB7 进行位反转,可以得到 0xedb88320,这就是 crc32.IEEE - torek
1个回答

6
使用与您的Java代码相同的多项式,您将获得相同的结果。
最常见的CRC-32多项式作为常量存在于“crc32”包中:crc32.IEEE = 0xedb88320
table := crc32.MakeTable(crc32.IEEE)

通过这个变化,你可以得到相同的结果。在 Go Playground 上试一下。


谢谢!在Torek添加评论后我才想到这个。 - saarthak gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接