2008-09-02 41 views
25

Tôi đang đọc một số giao thức MPEG Transport Stream qua UDP và nó có một số bitfield funky trong đó (chiều dài 13 ví dụ). Tôi đang sử dụng "struct" thư viện để làm việc giải nén rộng, nhưng là có một cách đơn giản để nói "Lấy 13 bit tiếp theo" thay vì phải tinh chỉnh tay thao tác bit? Tôi muốn một cái gì đó giống như cách C không bit lĩnh vực (mà không cần phải trở lại C).Cách tốt nhất để thực hiện thao tác Bit Field bằng Python là gì?

Đề xuất?

Trả lời

25

Module bitstring được thiết kế để giải quyết vấn đề này chỉ. Nó sẽ cho phép bạn đọc, sửa đổi và xây dựng dữ liệu bằng cách sử dụng bit như các khối xây dựng cơ bản. Các phiên bản mới nhất dành cho Python 2.6 hoặc mới hơn (bao gồm Python 3) nhưng phiên bản 1.0 cũng hỗ trợ Python 2.4 và 2.5.

Một ví dụ liên quan để bạn có thể có này, dùng để tách ra khỏi tất cả các gói null từ dòng truyền tải (và hoàn toàn có thể sử dụng trường bit 13 của bạn?):

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) 

Dưới đây là một ví dụ khác bao gồm đọc từ 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) 

Bạn có thể sử dụng ký hiệu lát tiêu chuẩn để cắt, xóa, đảo chiều, ghi đè, v.v. ở cấp bit và có chức năng tìm mức bit, thay thế, chia nhỏ. Các endianness khác nhau cũng được hỗ trợ.

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

Tài liệu đầy đủ là here.

+0

Tôi nghĩ rằng gói [11:24] .uint phải là gói [12:24] .uint. Trường dài 13 bit, bắt đầu từ bit 12, kết thúc tại bit 24. –

+0

Điều này thực sự là một nhận xét chứ không phải là câu trả lời, nhưng không, nó thực sự là [11:24]. Các chỉ số không dựa trên và không bao gồm chỉ mục kết thúc (là cách sử dụng chuẩn trong Python và nhiều ngôn ngữ khác). Vì vậy, một lát chỉ là bit đầu tiên sẽ là [0: 1], trong khi [12:24] sẽ là một lát 12 bit từ thứ 13 đến bit thứ 24. Lưu ý rằng độ dài luôn là sự khác biệt giữa hai chỉ số. –

Các vấn đề liên quan