【问题标题】:Is there any way to add two bytes with overflow in python?有没有办法在python中添加两个字节溢出?
【发布时间】:2009-06-10 21:03:09
【问题描述】:

我正在使用 pySerial 从连接的设备中读取数据。我想计算每个接收到的数据包的校验和。数据包作为 char 数组读入,实际校验和是数据包末尾的最后一个字节。为了计算校验和,我通常会对数据包有效负载求和,然后将其与实际校验和进行比较。

通常在像 C 这样的语言中,我们会期望溢出,因为校验和本身只有一个字节。我不确定python的内部结构,但根据我对语言的经验,它看起来会默认为更大的变量(可能是一些内部的 bigInt 类或其他东西)。无论如何,在不编写我自己的实现的情况下,是否可以模仿添加两个字符的预期行为?谢谢。

【问题讨论】:

    标签: python overflow checksum


    【解决方案1】:

    当然,只需将结果的模数重新调整为您想要的大小即可。您可以在最后或每一步进行模数。例如:

    >>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes
    >>> sum(payload) % 256 # modulo 256 to make the answer fit in a single byte
    254 # this would be your checksum
    

    【讨论】:

    • 不错的简单示例。请注意,另一种截断为字节的常用方法是与 0xFF 进行按位与运算,即“sum(payload) & 0xFF”。
    • @benhoyt 看起来我们在想同样的事情 ;-)
    【解决方案2】:

    为了改进前面的例子,只是按位 - 并且它使用 0xFF。不确定python是否默认进行优化。

    sum(bytes) & 0xFF
    

    【讨论】:

    • 我不确定 Python 在底层做了什么,但快速测试表明这两种方法花费的时间几乎相同。无论如何,总结将是大部分工作。
    • 大多数体面的优化编译器都会降低强度并将您的“% (2^n)”实现为“& ((1
    • 查看“dis.dis(lambda x:x%256)”的输出,似乎没有应用此优化。运行时的微小差异可能是由于实际的 and/mod 操作只占总成本的很小一部分。
    • 当您的数据来自串行端口时,您是否真的担心数学运算的性能???? ;)
    • CPython 解释器对每个字节码指令执行数百条指令。 &% 产生相同数量的字节码指令。与所有开销相比,它们相应的 CPU 指令不占用任何时间。 Related.(此外,&% 在现代处理器上可能会在相同的时钟周期内执行。)
    【解决方案3】:

    对字节求和然后取模,如sum(bytes) % 256(或sum(bytes) & 0xFF),(在许多编程语言中)容易受到整数溢出的影响,因为整数类型可以表示的最大值是有限的。

    但是,由于我们讨论的是 Python,这在技术上不是问题:Python 整数是任意精度的,因此不会发生整数溢出。

    如果要逐个元素执行取模运算,可以使用functools.reduce()

    >>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes
    # (Python 3 uses functools.reduce() instead of builtin reduce() function)
    >>> import functools
    >>> functools.reduce(lambda x,y: (x+y)%256, payload)
    254
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 2019-02-05
      • 1970-01-01
      相关资源
      最近更新 更多