2008-09-02 18 views
25

UDP üzerinden bazı MPEG Aktarım Akışı protokolünü okudum ve içinde biraz funf bitfields var (örneğin, uzunluk 13). Geniş açılımı yapmak için "struct" kütüphanesini kullanıyorum, ama bit manipülasyonunu elle düzenlemekten ziyade "Sonraki 13 biti tut" demenin basit bir yolu var mı? C'nin bit alanları (C'ye dönmek zorunda kalmadan) bitmesi gibi bir şey isterim.Python'da Bit Alanı manipülasyonunu yapmanın en iyi yolu nedir?

Öneriler?

cevap

25

yoktur. Temel yapı taşları olarak bitleri kullanarak verileri okumanıza, değiştirmenize ve oluşturmanıza izin verir. En son sürümler Python 2.6 veya üstü için (Python 3 dahil) ancak sürüm 1.0 destekli Python 2.4 ve 2.5 sürümleridir.

Sana bir ilgili örnek bir nakil akımından tüm boş paketler çıkarır ki, bu olabilir (ve büyük ihtimalle sizin 13 bit alanını kullanır?): Burada

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) 

çatılma okuma da dahil olmak üzere başka bir örnek :

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

vb bölmek yerine, bulmak fonksiyonları Sen bit düzeyinde, vb dilim silmek ters üzerine yazmak standart dilim notasyonu kullanabilir ve bit düzeyinde bulunmaktadır. Farklı endensiteler de desteklenmektedir.

# 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üm belgeler here'dir.

+0

Sanırım paket [11:24] .uint paket olmalı [12:24] .uint. Alan 13 bit uzunluğunda, bit 12'de başlıyor, 24 bitinde bitiyor. –

+0

Bu gerçekten bir yorum olmalı, bir cevap olmalı, ama hayır, gerçekten [11:24]. Endeksler sıfır bazlıdır ve endeks dahil değildir (Python ve diğer birçok dilde standart kullanım). Bu yüzden sadece ilk bitin bir dilim [0: 1] olurken, [12:24], 13'ten 24'üncü yüze kadar 12 bitlik bir dilim olurdu. Uzunluğun her zaman iki endeks arasındaki fark olduğunu unutmayın. –

İlgili konular