【问题标题】:Discrepant results between XOR operation in Javascript and PythonJavascript 和 Python 中的 XOR 运算结果不一致
【发布时间】:2017-04-23 15:43:16
【问题描述】:

我正在将一个长而丑陋的函数从 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 得到上面显示的值时,一切都开始混乱了。

【问题讨论】:

    标签: javascript python math operators xor


    【解决方案1】:

    区别在于有符号数的处理方式。 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)
    

    【讨论】:

    • 好吧,我尝试了您的解决方案,尽管起初它适用于我最初问题的值,但使用其他组合我仍然得到奇怪的结果。我终于结束了使用 ctypes.c_int 函数,它给了我更可靠的结果。我不知道为什么您应用该 32 位掩码的解决方案并不总是有效,但无论如何,感谢您给我一些提示!
    • @KilianPerdomo 您可能仍然会得到错误的结果符号,因此如果结果大于2**31 - 1,则必须调整符号。使用ctypes.c_int 可能是更简单的解决方案,尽管我不确定它是否保证有 32 位。为了安全起见,您可以使用ctypes.c_int32
    猜你喜欢
    • 1970-01-01
    • 2017-09-28
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    相关资源
    最近更新 更多