aleix's blog

Packing and unpacking bit structures in Python

16 June 2007 1:52 pm (bitpacket | python)

Last week, I released the first version of the BitPacket Python module which allows you to pack and unpack data like the struct and array modules, but in an object-oriented way. At work I needed an easy way to create network packets and at that time I did not know the existence of the struct and array modules, so I googled a bit and I found out the BitVector class for a memory-efficient packed representation of bit arrays, which I decided to use for my purpose.

I implemented three classes, BitField, BitStructure and BitVariableStructure (the lastest two are derived from BitField). A network packet would be represented by the BitStructure class, which at creation does not contain any field, and the idea is that any BitField subclass might be added to it.

I'll will show you the most basic example. Suppose, you need a simple network packet like the one below:

|  id (1 byte)  |  address (4 byte) |

You could easily create a network packet using BitStructure, like this:

>>> bs = BitStructure('mypacket')
>>> bs.append(BitField('id', BYTE_SIZE, 0x54))
>>> bs.append(BitField('address', INTEGER_SIZE, 0x10203040))

and print its contents:

>>> print bs
>>> (mypacket =
>>>   (id = 0x54)
>>>   (address = 0x10203040))

In order to unpack an incoming packet, we could use the variable created above or a new one without default values:

>>> bs = BitStructure('mypacket')
>>> bs.append(BitField('id', BYTE_SIZE))
>>> bs.append(BitField('address', INTEGER_SIZE))

In order to unpack an incoming array of bytes, we would do the following:

>>> data = array.array('B', [0x38, 0x87, 0x34, 0x21, 0x40])
>>> bs.set_stream(data)

We can then access to the packet fields by their name:

>>> print '0x%X' % bs['id']
>>> print '0x%X' % bs['address']

There are a lot more possibilities to pack and unpack bit field structures by using BitStructure and BitVariableStructure. You can see all of them in the module's online documentation.

11 responses

  1. Sebastian says:

    How about dynamic length fields like in your first example. Quite often packets have data as last field. Can you somehow tell BitField that last field is custom sized? Now I have to calculate the starting location of the data myself to grab it.

  2. aleix says:

    Right now this is not possible. I'm working on a new version where this will be possible, but I'm not sure when it will be available.

    Right now BitPacket is quite simple and the performance is very slow. You might be interested to try a more robust library like construct.

  3. says:

    This is really great work. Thank you for sharing such a good and useful information here in the blog for students.

  4. says:

    This is really great work. Thank you for sharing such a good and useful information here in the blog for students.

  5. Programming Assignment Help Online says:

    Great info! I recently came across your blog and have been reading along. I thought I would leave my first comment. I don’t know what to say except that I have

  6. Carolina says:

    This article is very interesting.

  7. kevin33e says:

    Wow it looks really awesome

  8. Bruno4 says:

    This post is very helpful.

  9. Won-Shik099 says:

    People who want to know about the packing and unpacking bit Structures in Python which is web and software development language. Now in this post, You told the actual way to proceed it. However, I try to get reviews but i think junior python developer must get advantages from this post.

  10. Minecraft apk says:

    wow... what a great blog,

  11. Hay Day mod apk says:

    Thanks a lot for sharing this useful information.

Leave a Reply