[Tutor] Bit-level field extraction

Kent Johnson kent37 at tds.net
Tue May 16 12:03:04 CEST 2006


Terry Carroll wrote:
> I want to see if I'm reinventing a wheel here, or maybe doing it 
> unpythonically.
> 
> I need to extract from a byte (i.e., a one-character string) a field of an
> certain number of bits.  For example, a certain byte of an MP3 frame
> header has the format xxxVVxxx, where the value of VV (00, 01, 10 or 11)
> tels what version of MPEG Audio is being used.  The other bits marked 'x'
> are not relevant to the version id, and may be 1s or 0s.
> 
> Here's my stab:
> 
> def getbits(byte, fieldlength, rightpad):
>     '''
>     returns an integer with the value derived from a string of bits of
>     length fieldlength, right-padded with rightpad number of bits.
>     e.g., getbyte(byte, 2, 3) returns a value from bits 3-4
>     (counting from the right)
>     '''
>     bitmask = (2**fieldlength-1) << rightpad
>     return (ord(byte) & bitmask) >> rightpad
> 
> testbytes = ["\xC0", "\x08", "\xF0", "\x19"]
> for byte in testbytes:
>     print getbits(byte, 2, 3)
>     # should get 0, 1, 2, 3
> 
> 
> This works (at least for these 4 test cases).  But is this the best way to 
> extract a bit-level field, or am I missing some appropriate module or 
> something?

You might be interested in Construct, it aims to make it easy to parse 
and create structures based on bit fields:
http://pyconstruct.wikispaces.com/

It seems to work by assembling a string representing the bit values of 
the target, then converting to binary. My guess is your method will be 
faster but Construct looks pretty convenient to work with.

If you try it let us know how it goes...
Kent



More information about the Tutor mailing list