¿Cuál es la mejor manera de hacer la manipulación de Campos de bits en Python?


Estoy leyendo algunos MPEG Transport Stream protocol sobre UDP y tiene algunos bitfields funky en él (longitud 13, por ejemplo). Estoy usando la biblioteca " struct "para hacer el desempaquetado amplio, pero ¿hay una manera simple de decir" Agarra los próximos 13 bits " en lugar de tener que ajustar a mano la manipulación de bits? Me gustaría algo como la forma en que C hace los campos de bits (sin tener que volver a C).

Sugerencias?

Author: Grace Note, 2008-09-02

2 answers

Es una pregunta frecuente. Hay un Libro de cocina de ASPN entrada en él que me ha servido en el pasado.

Y hay una página extensa de requisitos que a una persona le gustaría ver de un módulo haciendo esto.

 8
Author: Thomas Vander Stichele,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-02 15:13:44

El módulo bitstring está diseñado para resolver este problema. Le permitirá leer, modificar y construir datos utilizando bits como los bloques de construcción básicos. Las últimas versiones son para Python 2.6 o posterior (incluido Python 3), pero la versión 1.0 también admite Python 2.4 y 2.5.

Un ejemplo relevante para usted podría ser este, que elimina todos los paquetes nulos de un flujo de transporte (y muy posiblemente utiliza su campo de 13 bits?):

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)

Aquí hay otro ejemplo incluyendo la lectura de bitstreams:

# 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)

Puede usar la notación de corte estándar para cortar, eliminar, invertir, sobrescribir, etc. en el nivel de bits, y hay nivel de bits buscar, reemplazar, dividir, etc. función. También se admiten diferentes endianidades.

# 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()

La documentación completa está aquí.

 25
Author: Scott Griffiths,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-13 16:49:36