我正在实施adler32 checksum的滚动版本。
这个答案有助于仔细检查我的数学。但是我正在努力在 golang 中正确实现它。
我写了以下代码:
func roll(adler, n, leave, enter uint32) uint32 {
a := adler & 0xffff
b := adler >> 16
a = (a + enter - leave) % MOD
b = (b - n*leave - 1 + a) % MOD
return b<<16 | a
}
它在各种输入上对其进行了测试,并且运行良好,直到我决定在随机数据上运行它。这是一个不起作用的示例(我发现了其中几个)。
令我困惑的是,python 中的相同代码在这些输入上完美运行:
def roll(adler, n, leave, enter):
a = adler & 0xffff
b = adler >> 16
a = (a + enter - leave) % MOD
b = (b - n*leave - 1 + a) % MOD
return b<<16 | a
为了更好地衡量,我包括证明这在 python 中有效。请注意,python 校验和与 go 校验和的非滚动版本匹配(并且该部分直接来自 go 核心库)。
我研究了所有其他有问题的样本的结果,发现我从来没有在校验和的最低有效位(“a”位)上犯错。此外,误差始终相同,等于0xe10000
。我怀疑 go 如何处理对 uint32 整数的模运算的特殊性是造成这种情况的原因。
发生了什么以及如何修复我的代码?