Qual é a melhor maneira de fazer manipulação Campo Bit em Python?

votos
25

Estou lendo algum protocolo MPEG Transport Stream sobre UDP e tem algumas bitfields funky no-lo (comprimento 13, por exemplo). Eu estou usando a biblioteca struct para fazer a ampla descompactação, mas há uma maneira simples de dizer Pegue os próximos 13 bits em vez de ter a mão-ajustar a manipulação de bits? Eu gostaria algo como o caminho C faz campos de bits (sem ter que reverter para C).

Sugestões?

Publicado 02/09/2008 em 15:28
fonte usuário
Em outras línguas...                            


2 respostas

votos
25

O bitstring módulo foi projetado para atender apenas este problema. Ele permitirá que você ler, modificar e construir dados usando bits como os blocos básicos de construção. As versões mais recentes são para Python 2.6 ou posterior (incluindo Python 3), mas a versão 1.0 suportado Python 2.4 e 2.5 também.

Um exemplo relevante para você pode ser esta, que retira todos os pacotes nulos a partir de um fluxo de transporte (e muito possivelmente usa seu 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)

Aqui está outro exemplo, incluindo a leitura de fluxos de bits:

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

Você pode usar a notação de fatia padrão de cortar, apagar, reverso, substituir, etc. no nível de bit, e há achado nível de bit, substitua, dividir etc. funções. Diferentes endiannesses também são suportados.

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

A documentação completa está aqui .

Respondeu 06/07/2009 em 13:20
fonte usuário

votos
8

É uma pergunta frequentemente feita. Há uma ASPN Cookbook entrada nele que me serviu no passado.

E há uma extensa página de requisitos de uma pessoa gostaria de ver a partir de um módulo de fazer isso.

Respondeu 02/09/2008 em 16:13
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more