我正在将一个漫长而丑陋的函数从JS移植到Python,基本上在给定一些输入参数的情况下计算某种哈希字符串。在移植和调整代码之后,进行了一些测试,并且(惊喜),我得不到相同的结果。
我做了一些调试,然后到了开始搞乱一切的线路,结果是一个XOR操作。所以,长话短说,我已经分离出一个简单的例子,它显示了如何使用相同的值获得不同的结果。
这是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获得上面显示的值时,一切都开始变得混乱。
答案 0 :(得分:5)
不同之处在于如何处理签名号码。 Python将整数视为在所有上下文中具有任意位长度。对于位操作,负数被视为具有“足够”导致一位用于任何目的,因此对具有正数的负数进行异或将始终导致负数。另一方面,在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)