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