Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Packing 4 Integers as ONE BYTE?

I have four integers {a, b, c, d} that can have the following range of values:

a - {0 or 1} (1 bit)

b - {0 or 1} (1 bit)

c - {0, 1, 2, ..., 7} (3 bits)

d - {0, 1, 2, ..., 7} (3 bits)

at first, I would like to pack them into a one byte that can be then written to a binary file. later, I would like to unpack that one byte and get from it to a tuple of the form (a, b, c, d).

I know how to read/write a byte to a binary file in python. But how do I do the bits packing/unpacking?

like image 995
user3262424 Avatar asked Mar 14 '11 17:03

user3262424


People also ask

What are packed bytes?

What is Packed data? The Packed data type is used by mainframe operating systems to store numeric values in a format that uses minimal storage space. The Packed data type stores two digits in each byte, and the last byte indicates whether the value is positive or negative.

What is integer packing?

An integer packing set is a set of non-negative integer vectors with the property that, if a vector x is in the set, then every non-negative integer vector y with y \leq x is in the set as well.

What is packing and unpacking data?

packing and unpacking of data occurs in some computer languages as a means of grouping the data together, or reducing its size, or both.


1 Answers

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 & 1
b = (i >> 1) & 1
c = (i >> 2) & 7
d = (i >> 5) & 7

Explanation: Initially, you have

0000000a
0000000b
00000ccc
00000ddd

The left-shifts give you

0000000a
000000b0
000ccc00
ddd00000

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

dddcccba
0dddcccb
00dddccc
00000ddd

Masking (bitwise AND) with 1 (0b00000001) or 7 (0b00000111) results in

0000000a
0000000b
00000ccc
00000ddd

again.

like image 137
Sven Marnach Avatar answered Sep 28 '22 00:09

Sven Marnach