Converting bits to bytes in Python Converting bits to bytes in Python python-3.x python-3.x

Converting bits to bytes in Python


The simplest tactics to consume bits in 8-er chunks and ignore exceptions:

def getbytes(bits):    done = False    while not done:        byte = 0        for _ in range(0, 8):            try:                bit = next(bits)            except StopIteration:                bit = 0                done = True            byte = (byte << 1) | bit        yield byte

Usage:

lst = [1,0,0,0,0,0,0,0,1]for b in getbytes(iter(lst)):    print b

getbytes is a generator and accepts a generator, that is, it works fine with large and potentially infinite streams.


Step 1: Add in buffer zeros

Step 2: Reverse bits since your endianness is reversed

Step 3: Concatenate into a single string

Step 4: Save off 8 bits at a time into an array

Step 5: ???

Step 6: Profit

def bitsToBytes(a):    a = [0] * (8 - len(a) % 8) + a # adding in extra 0 values to make a multiple of 8 bits    s = ''.join(str(x) for x in a)[::-1] # reverses and joins all bits    returnInts = []    for i in range(0,len(s),8):        returnInts.append(int(s[i:i+8],2)) # goes 8 bits at a time to save as ints    return returnInts


Using itertools' grouper()` recipe:

from functools import reducefrom itertools import zip_longestdef grouper(iterable, n, fillvalue=None):    "Collect data into fixed-length chunks or blocks"    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"    args = [iter(iterable)] * n    return zip_longest(*args, fillvalue=fillvalue)bytes = [reduce(lambda byte, bit: byte << 1 | bit, eight_bits)         for eight_bits in grouper(bits, 8, fillvalue=0)]

Example

[] -> [][1] -> [128][1, 1] -> [192][1, 0, 0, 0, 0, 0, 0, 0, 1] -> [128, 128]

If input is a string then a specialized solution might be faster:

>>> bits = '100000001'>>> padded_bits = bits + '0' * (8 - len(bits) % 8)>>> padded_bits'1000000010000000'>>> list(int(padded_bits, 2).to_bytes(len(padded_bits) // 8, 'big'))[128, 128]

The last byte is zero if len(bits) % 8 == 0.