【问题标题】:What is the best way to do Bit Field manipulation in Python?在 Python 中进行位域操作的最佳方法是什么?
【发布时间】:2010-09-07 13:38:09
【问题描述】:

我正在通过 UDP 读取一些 MPEG 传输流协议,其中包含一些时髦的位域(例如长度 13)。我正在使用“struct”库进行广泛的解包,但有没有一种简单的方法可以说“抓住接下来的 13 位”而不是手动调整位操作?我想要类似于 C 处理位字段的方式(无需恢复为 C)。

建议?

【问题讨论】:

    标签: python udp bits bit-fields


    【解决方案1】:

    bitstring 模块旨在解决这个问题。它将允许您使用位作为基本构建块来读取、修改和构造数据。最新版本适用于 Python 2.6 或更高版本(包括 Python 3),但 1.0 版本也支持 Python 2.4 和 2.5。

    一个相关的例子可能是这个,它从传输流中去除所有空数据包(很可能使用你的 13 位字段?):

    from bitstring import Bits, BitStream  
    
    # Opening from a file means that it won't be all read into memory
    s = Bits(filename='test.ts')
    outfile = open('test_nonull.ts', 'wb')
    
    # Cut the stream into 188 byte packets
    for packet in s.cut(188*8):
        # Take a 13 bit slice and interpret as an unsigned integer
        PID = packet[11:24].uint
        # Write out the packet if the PID doesn't indicate a 'null' packet
        if PID != 8191:
            # The 'bytes' property converts back to a string.
            outfile.write(packet.bytes)
    

    这是另一个例子,包括从比特流中读取:

    # You can create from hex, binary, integers, strings, floats, files...
    # This has a hex code followed by two 12 bit integers
    s = BitStream('0x000001b3, uint:12=352, uint:12=288')
    # Append some other bits
    s += '0b11001, 0xff, int:5=-3'
    # read back as 32 bits of hex, then two 12 bit unsigned integers
    start_code, width, height = s.readlist('hex:32, 2*uint:12')
    # Skip some bits then peek at next bit value
    s.pos += 4
    if s.peek(1):
        flags = s.read(9)
    

    您可以使用标准的切片表示法在位级别进行切片、删除、反转、覆盖等,并且有位级别的查找、替换、拆分等功能。还支持不同的字节顺序。

    # Replace every '1' bit by 3 bits
    s.replace('0b1', '0b001')
    # Find all occurrences of a bit sequence
    bitposlist = list(s.findall('0b01000'))
    # Reverse bits in place
    s.reverse()
    

    完整的文档是here

    【讨论】:

    • 我认为 packet[11:24].uint 应该是 packet[12:24].uint。该字段长 13 位,从第 12 位开始,在第 24 位结束。
    • 这确实应该是评论而不是答案,但不,确实是 [11:24]。索引从零开始,不包括结束索引(这是 Python 和许多其他语言的标准用法)。因此,只有第一位的切片将是 [0:1],而 [12:24] 将是从第 13 位到第 24 位(含)的 12 位切片。请注意,长度始终是两个索引之间的差。
    【解决方案2】:

    这是一个经常被问到的问题。上面有一个 ASPN Cookbook 条目,过去曾为我服务过。

    还有一个extensive page of requirements one person would like to see from a module doing this.

    【讨论】:

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