Packing 4 Integers as ONE BYTE?
Use shift and bitwise OR, then convert to a character to get a "byte":
x = chr(a | (b << 1) | (c << 2) | (d << 5))
To unpack this byte again, first convert to an integer, then shift and use bitwise AND:
i = ord(x)a = i & 1b = (i >> 1) & 1c = (i >> 2) & 7d = (i >> 5) & 7
Explanation: Initially, you have
0000000a0000000b00000ccc00000ddd
The left-shifts give you
0000000a000000b0000ccc00ddd00000
The bitwise OR results in
dddcccba
Converting to a character will convert this to a single byte.
Unpacking: The four different right-shifts result in
dddcccba0dddcccb00dddccc00000ddd
Masking (bitwise AND) with 1
(0b00000001
) or 7
(0b00000111
) results in
0000000a0000000b00000ccc00000ddd
again.
If you need to this kind of thing a lot then bit shifting can become tedious and error prone. There are third-party libraries that can help - I wrote one called bitstring:
To pack and convert to a byte:
x = bitstring.pack('2*uint:1, 2*uint:3', a, b, c, d).bytes
and to unpack:
a, b, c, d = bitstring.BitArray(bytes=x).unpack('2*uint:1, 2*uint:3')
This is probably overkill for your example, but it's helpful when things get more complicated.