Reputation: 1141
I have an integer that is 8 bits and I want to distribute these bits into beginnings of 4 integers (4x8 bit) two by two. For example:
bit_8 = 0b_10_11_00_11
bit_32 = b"\x12\x32\x23\54" # --> [0b100_10, 0b1100_10, 0b1000_11, 0b1011_00]
what_i_want = [0b100_10, 0b1100_11, 0b1000_00, 0b1011_11]
For readability I wrote numbers in a list, but I want them as bytes
. I am not very good at bit manipulations and I couldn't find a good way.
I will repeat this process many times, so I need a fast solution. I found a way of setting bits by one by at here, but I wonder if there is a better way for my problem.
Language is not so important, I need an algorithm. Nevertheless I prefer Python.
Upvotes: 0
Views: 150
Reputation: 24262
You could do it by iterating in reverse on bit_32
, and at the same time taking the last two bits of bit_8
, then shifting it right.
This way, you can build a list of the output values, in reverse order, which you can reorder while converting to bytes.
bit_8 = 0b_10_11_00_11
bit_32 = b"\x12\x32\x23\54" # --> [0b100_10, 0b1100_10, 0b1000_11, 0b1011_00]
what_i_want = [0b100_10, 0b1100_11, 0b1000_00, 0b1011_11]
out_lst = []
for b in reversed(bit_32):
bits_from_bit_8 = bit_8 & 0b11 # last two bits of bit_8
bit_8 >>= 2 # we shift it right by to bits
out_lst.append(b & 0b11111100 | bits_from_bit_8)
out = bytes(reversed(out_lst))
print(out)
#b'\x123 /'
# Check that this is the expected output:
print([i for i in out], what_i_want)
# [18, 51, 32, 47] [18, 51, 32, 47]
Upvotes: 1