Add code and packaging structure
This commit is contained in:
1 parent
e42c911305
commit
ff3e8eddb7
3 files changed
+128
-1
No files matched your search
+106
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
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')}")
|
||||
Reference in new issue
Block a user