Examples

Creation

There are lots of ways of creating new bitstrings. The most flexible is via the auto parameter, which is used in this example.

# Multiple parts can be joined with a single expression...
s = BitArray('0x000001b3, uint:12=352, uint:12=288, 0x1, 0x3')

# and extended just as easily
s += 'uint:18=48000, 0b1, uint:10=4000, 0b100'

# To covert to an ordinary string use the bytes property
open('video.m2v', 'wb').write(s.bytes)

# The information can be read back with a similar syntax
start_code, width, height = s.readlist('hex:32, uint:12, uint:12')
aspect_ratio, frame_rate = s.readlist('2*bin:4')

Manipulation

s = BitArray('0x0123456789abcdef')

del s[4:8]                      # deletes the '1'
s.insert('0xcc', 12)            # inserts 'cc' between the '3' and '4'
s.overwrite('0b01', 30)         # changes the '6' to a '5'

# This replaces every '1' bit with a 5 byte Ascii string!
s.replace('0b1', BitArray(bytes='hello'))

del s[-1001:]                   # deletes final 1001 bits
s.reverse()                     # reverses whole BitString
s.prepend('uint:12=44')         # prepend a 12 bit integer

Parsing

This example creates a class that parses a structure that is part of the H.264 video standard.

class seq_parameter_set_data(object):
    def __init__(self, s):
        """Interpret next bits in BitString s as an SPS."""
        # Read and interpret bits in a single expression:
        self.profile_idc = s.read('uint:8')
        # Multiple reads in one go returns a list:
        self.constraint_flags = s.readlist('4*uint:1')
        self.reserved_zero_4bits = s.read('bin:4')
        self.level_idc = s.read('uint:8')
        self.seq_parameter_set_id = s.read('ue')
        if self.profile_idc in [100, 110, 122, 244, 44, 83, 86]:
            self.chroma_format_idc = s.read('ue')
            if self.chroma_format_idc == 3:
                self.separate_colour_plane_flag = s.read('uint:1')
            self.bit_depth_luma_minus8 = s.read('ue')
            self.bit_depth_chroma_minus8 = s.read('ue')
            # etc.
>>> s = BitStream('0x6410281bc0')
>>> sps = seq_parameter_set_data(s)
>>> print(sps.profile_idc)
100
>>> print(sps.level_idc)
40
>>> print(sps.reserved_zero_4bits)
0b0000
>>> print(sps.constraint_flags)
[0, 0, 0, 1]

Sieve of Eratosthenes

This classic (though inefficient) method of calculating prime numbers uses a bitstring to store whether each bit position represents a prime number. This takes much less memory than an ordinary array.

def prime_sieve(top=1000000):
    b = BitArray(top) # bitstring of '0' bits
    for i in xrange(2, top):
        if not b[i]:
            yield i
            # i is prime, so set all its multiples to '1'.
            b.set(True, xrange(i*i, top, i))