Javascript 和 Python 中的 XOR 运算结果不一致

Discrepant results between XOR operation in Javascript and Python

我正在将一个又长又丑的函数从 JS 移植到 Python,它基本上是在给定一些输入参数的情况下计算某种哈希字符串。移植和调整代码后,做了一些测试,并且(令人惊讶的是),我没有得到相同的结果。

我进行了一些调试,然后到了开始弄乱一切的那一行,原来是异或运算。所以,长话短说,我已经隔离了一个简单的例子,它展示了如何使用相同的值,获得不同的结果。

这是JS代码:

hex_str = "0xA867DF55"
crc = -1349196347
new_crc = (crc >> 8) ^ hex_str
//new_crc == 1472744368

这与 Python 中的代码相同:

hex_str = "0xA867DF55"
crc = -1349196347
new_crc = (crc >> 8) ^ int(hex_str, 16)
//new_crc == -2822222928

唯一的区别是 hex_str 在 Python 中被显式转换为整数。

在实际代码中,此计算在 for 循环中运行。 hex_str 和 crc 在每次迭代时都会更新。在最初的几次迭代中,python 中一切正常,但是当 hex_str 和 crc 获得上面显示的值时,一切开始变得混乱。

不同之处在于如何处理带符号的数字。 Python 在所有上下文中都将整数视为具有任意位长度。对于位操作,出于任何目的,负数都被视为具有 "enough" 前导一位,因此将负数与正数异或将始终得到负数。另一方面,JavaScript中,位运算中的整数被视为带符号的32位数字,因此结果可能不同。

CRC32 是使用 32 位整数计算的。要模拟 Python 中的行为,您可以通过取任何结果的低 32 位来将所有操作限制为 32 位:

>>> -2822222928 & (2 ** 32 - 1)
1472744368

或应用于您的代码

hex_str = "0xA867DF55"
crc = -1349196347
new_crc = ((crc >> 8) ^ int(hex_str, 16)) & (2 ** 32 - 1)