Got asked to create an automated bot using Mastodon APIs so I did :)
I'll say more about it another day but I while creating it I thought about something that lots of people I know get confused: bytes and bits, so I make a short code snippets to convert and showcase the differences.
def bytes_to_bits(byte_count: int) -> int:
return byte_count * 8
def bits_to_bytes(bit_count: int) -> int:
# floor division (no half-bytes possible)
return bit_count // 8
def bytes_to_bits(byte_seq: bytes, sep: str = " ") -> str:
"""
Convert a sequence of bytes into a string of bits.
Each byte is 8 bits, padded with leading zeros.
:param byte_seq: bytes object (b'abc' or b'\xff\x10')
:param sep: separator string between bytes (default: space)
:return: bit string (e.g. '01100001 01100010')
"""
return sep.join(f"{byte:08b}" for byte in byte_seq)
def bits_to_bytes(bit_str: str, sep: str = " ") -> bytes:
"""
Convert a bit string back into raw bytes.
:param bit_str: string of bits (with optional separators)
:param sep: separator used between bytes (default: space)
:return: bytes object
"""
# Remove separators if present
parts = bit_str.split(sep) if sep else [bit_str]
return bytes(int(part, 2) for part in parts if part)
print(bytes_to_bits(512)) # 4096 bits
print(bits_to_bytes(4096)) # 512 bytes
data = b"A" # ASCII 65
bitstring = bytes_to_bits(data)
print(bitstring) # '01000001'
data2 = b"Hi"
print(bytes_to_bits(data2, sep="|"))
# '01001000|01101001'
# Back to bytes
recovered = bits_to_bytes(bitstring)
print(recovered) # b'A'
recovered2 = bits_to_bytes("01001000|01101001", sep="|")
print(recovered2.decode()) # 'Hi'
Since API calls use network, those are usually stored in byte size chunks and each bit is important. b"string" will create a byte version of that string where each character is a byte. I added a bit separator so each bit value can be used individually if needed. I hope you have fun with binary
~IO
Top comments (0)