I have 23 bits represented as a string, and I need to write this string to a binary file as 4 bytes. The last byte is always 0. The following code works (Python 3.3), but it doesn't feel very elegant (I'm rather new to Python and programming). Do you have any tips of making it better? It seems a for-loop might be useful, but how do I do the slicing within the loop without getting a IndexError? Note that that when I extract the bits into a byte, I reverse the bit-order.
from array import array
bin_array = array("B")
bits = "10111111111111111011110" #Example string. It's always 23 bits
byte1 = bits[:8][::-1]
byte2 = bits[8:16][::-1]
byte3 = bits[16:][::-1]
bin_array.append(int(byte1, 2))
bin_array.append(int(byte2, 2))
bin_array.append(int(byte3, 2))
bin_array.append(0)
with open("test.bnr", "wb") as f:
f.write(bytes(bin_array))
# Writes [253, 255, 61, 0] to the file
You can treat it as an int, then create the 4 bytes as follows:
>>> bits = "10111111111111111011110"
>>> int(bits[::-1], 2).to_bytes(4, 'little')
b'\xfd\xff=\x00'
The struct
module was designed for exactly this sort of thing — consider the following in which the conversion to bytes has been broken down into some unnecessary intermediate steps to make understanding it clearer:
import struct
bits = "10111111111111111011110" # example string. It's always 23 bits
int_value = int(bits[::-1], base=2)
bin_array = struct.pack('i', int_value)
with open("test.bnr", "wb") as f:
f.write(bin_array)
A harder-to-read, but shorter, way would be:
bits = "10111111111111111011110" # example string. It's always 23 bits
with open("test.bnr", "wb") as f:
f.write(struct.pack('i', int(bits[::-1], 2)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With