Как лучше всего манипулировать битовыми полями в Python?

StackOverflow https://stackoverflow.com/questions/39663

  •  09-06-2019
  •  | 
  •  

Вопрос

Я читаю какой-то протокол транспортного потока MPEG через UDP, и в нем есть несколько причудливых битовых полей (например, длина 13).Я использую библиотеку «struct» для выполнения широкой распаковки, но есть ли простой способ сказать «захватите следующие 13 битов» вместо того, чтобы вручную настраивать манипуляции с битами?Мне бы хотелось что-то вроде того, как C обрабатывает битовые поля (без необходимости возвращаться к C).

Предложения?

Это было полезно?

Решение

Это часто задаваемый вопрос.Есть Поваренная книга АСПН запись об этом, которая послужила мне в прошлом.

И есть обширная страница требований, которые один человек хотел бы видеть в модуле, выполняющем это.

Другие советы

битовая строка Модуль предназначен именно для решения этой проблемы.Он позволит вам читать, изменять и конструировать данные, используя биты в качестве основных строительных блоков.Последние версии предназначены для 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()

Полная документация есть здесь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top