Files

106 lines
2.8 KiB
Python

"""
Implementation of Base122 in pure Python.
It attempts to mirror behaviour of the base64 built-in module.
Its API is not yet complete or final. This is a first version for testing.
"""
illegals = [0, 10, 13, 34, 38, 92]
def b122encode(raw_data):
if isinstance(raw_data, str):
raise ValueError("Input should be bytes")
out_data = []
cur_index = 0
cur_bit = 0
def get_7():
nonlocal cur_index, cur_bit
if cur_index >= len(raw_data):
return False
first_byte = raw_data[cur_index]
first_part = ((0b11111110 >> cur_bit) & first_byte) << cur_bit
first_part >>= 1
cur_bit += 7
if cur_bit < 8:
return first_part
cur_bit -= 8
cur_index += 1
if cur_index >= len(raw_data):
return first_part
second_byte = raw_data[cur_index]
second_part = ((0xFF00 >> cur_bit) & second_byte) & 0xFF
second_part >>= 8 - cur_bit
return first_part | second_part
while True:
bits = get_7()
if bits is False:
break
illegal_index = illegals.index(bits) if bits in illegals else None
if illegal_index is not None:
next_bits = get_7()
b1 = 0b11000010
b2 = 0b10000000
if next_bits is False:
b1 |= 7 << 2
next_bits = bits
else:
b1 |= (illegal_index & 0b111) << 2
first_bit = (next_bits & 0b01000000) > 0
b1 |= first_bit
b2 |= next_bits & 0b00111111
out_data.append(b1)
out_data.append(b2)
else:
out_data.append(bits)
return bytes(out_data)
def b122decode(base122_data):
decoded = []
cur_byte = 0
bit_of_byte = 0
def push7(byte):
nonlocal cur_byte, bit_of_byte
byte <<= 1
cur_byte |= (byte >> bit_of_byte)
bit_of_byte += 7
if bit_of_byte >= 8:
decoded.append(cur_byte & 0xFF)
bit_of_byte -= 8
cur_byte = (byte << (7 - bit_of_byte)) & 0xFF
for c in base122_data:
if c > 127:
illegal_index = (c >> 8) & 7
if illegal_index != 7:
push7(illegals[illegal_index])
push7(c & 127)
else:
push7(c)
return bytes(decoded)
if __name__ == "__main__":
original_data = b"Hello World!"
encoded_data = b122encode(original_data)
print(f"Encoded data: {encoded_data}")
decoded_data = b122decode(encoded_data)
print(f"Decoded data: {decoded_data}")
original_data = 'Something else 🫨'.encode('utf-8')
encoded_data = b122encode(original_data)
print(f"Encoded data: {encoded_data.decode('utf8')}")
decoded_data = b122decode(encoded_data)
print(f"Decoded data: {decoded_data.decode('utf-8')}")