代码之家  ›  专栏  ›  技术社区  ›  Kimvais

在Python中处理八位字节内的4位的正确方法是什么

  •  1
  • Kimvais  · 技术社区  · 16 年前

    我正在编写一个应用程序来解析某些网络包。数据包字段以八进制形式包含协议版本号,因此4个高位是“主”位,4个低位是“次”位。目前,我正在对它们进行如下分析,但我想知道是否有一种更漂亮或更“蟒蛇式”的分析方法:

        v = ord(data[17])
        major = (v & int('11110000',2) ) >> 4
        minor = v & int('00001111',2)
    
    4 回复  |  直到 16 年前
        1
  •  2
  •   John La Rooy    16 年前

    您可以这样编写二进制文本 0b1111000

    但在你的例子中,我会不顾一切地使用十六进制

    v = ord(data[17])
    major = (v & 0xF0) >> 4
    minor = (v & 0x0F)
    

    您可能还想使用 struct 将数据包分解为其组件的模块

        2
  •  2
  •   Ants Aasma    16 年前

    命名函数总是隐藏丑陋和不相关的复杂性的好方法。通过这种方式,比特篡改被限制在小的、容易被证明是正确的函数中,而更高级别的代码可以引用篡改的目的。

    def high_nibble(byte):
        """Get 4 high order bits from a byte."""
        return (byte >> 4) & 0xF
    
    def low_nibble(byte):
        """Get 4 low order bits from a byte."""
        return byte & 0xF
    
    def parse_version(version_byte):
        """Get the major-minor version tuple from the version byte."""
        return high_nibble(version_byte), low_nibble(version_byte)
    
    major, minor = parse_version(version_byte)
    
        3
  •  1
  •   Scott Griffiths    16 年前

    使用文字而不是调用 int . 您可以使用二进制文字或十六进制,例如:

    major = (v & 0xf0) >> 4
    minor = (v & 0x0f)
    

    二进制文本仅适用于python 2.6或更高版本,其形式为 0b11110000 . 如果您使用的是python 2.6或更高版本,那么您可能需要查看 bytearray 键入,这样可以将数据视为二进制数据,因此不必使用 ord .

    如果您正在分析二进制数据,并且发现必须执行大量位操作,那么您可能需要尝试更通用的解决方案,因为有一些第三方模块专门从事这方面的工作。一个是 hachoir 一个较低级别的替代方案是 bitstring (我写的)。在这种情况下,您的解析将变得类似于:

    major, minor = data.readlist('uint:4, uint:4')
    

    如果你读了很多这样的书,这会更容易管理。

        4
  •  0
  •   fortran    16 年前

    只是一个提示,你最好给少校戴上口罩 之后 移位,以防为负数,符号保留:

    major = (v >> 4) & 0x0f
    minor = (v & 0x0f)