From 597581c0ed4912c72957f7115b2549591b4b9378 Mon Sep 17 00:00:00 2001 From: Chris O <46587501+ChrisO345@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:41:53 +1200 Subject: [PATCH 1/3] rewrite of base32.py --- ciphers/base32.py | 53 ++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/ciphers/base32.py b/ciphers/base32.py index fee53ccaf0c4..fed8f993f483 100644 --- a/ciphers/base32.py +++ b/ciphers/base32.py @@ -1,42 +1,47 @@ -import base64 +""" +Base32 encoding and decoding +https://en.wikipedia.org/wiki/Base32 +""" +B32_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" -def base32_encode(string: str) -> bytes: + +def base32_encode(data: bytes) -> bytes: """ - Encodes a given string to base32, returning a bytes-like object - >>> base32_encode("Hello World!") + >>> base32_encode(b"Hello World!") b'JBSWY3DPEBLW64TMMQQQ====' - >>> base32_encode("123456") + >>> base32_encode(b"123456") b'GEZDGNBVGY======' - >>> base32_encode("some long complex string") + >>> base32_encode(b"some long complex string") b'ONXW2ZJANRXW4ZZAMNXW24DMMV4CA43UOJUW4ZY=' """ - - # encoded the input (we need a bytes like object) - # then, b32encoded the bytes-like object - return base64.b32encode(string.encode("utf-8")) + binary_data = "".join([bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")]) + binary_data = binary_data.ljust(5 * ((len(binary_data) // 5) + 1), "0") + b32_chunks = map("".join, zip(*[iter(binary_data)] * 5)) + b32_result = "".join(j for j in map(lambda _s: B32_CHARSET[int(_s, 2)], b32_chunks)) + return bytes(b32_result.ljust(8 * ((len(b32_result) // 8) + 1), "="), "utf-8") -def base32_decode(encoded_bytes: bytes) -> str: +def base32_decode(data: bytes) -> bytes: """ - Decodes a given bytes-like object to a string, returning a string >>> base32_decode(b'JBSWY3DPEBLW64TMMQQQ====') - 'Hello World!' + b'Hello World!' >>> base32_decode(b'GEZDGNBVGY======') - '123456' + b'123456' >>> base32_decode(b'ONXW2ZJANRXW4ZZAMNXW24DMMV4CA43UOJUW4ZY=') - 'some long complex string' + b'some long complex string' """ - - # decode the bytes from base32 - # then, decode the bytes-like object to return as a string - return base64.b32decode(encoded_bytes).decode("utf-8") + binary_chunks = "".join( + map( + lambda _d: bin(B32_CHARSET.index(_d))[2:].zfill(5), + data.decode("utf-8").strip("="), + ) + ) + binary_data = list(map("".join, zip(*[iter(binary_chunks)] * 8))) + return bytes("".join(list(map(lambda _d: chr(int(_d, 2)), binary_data))), "utf-8") if __name__ == "__main__": - test = "Hello World!" - encoded = base32_encode(test) - print(encoded) + import doctest - decoded = base32_decode(encoded) - print(decoded) + doctest.testmod() From 52e28e5ec91b432922661c2604ff8caee8e37f21 Mon Sep 17 00:00:00 2001 From: Chris O <46587501+ChrisO345@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:58:19 +1200 Subject: [PATCH 2/3] changed maps to list comprehension --- ciphers/base32.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ciphers/base32.py b/ciphers/base32.py index fed8f993f483..d298b76c1a24 100644 --- a/ciphers/base32.py +++ b/ciphers/base32.py @@ -18,7 +18,9 @@ def base32_encode(data: bytes) -> bytes: binary_data = "".join([bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")]) binary_data = binary_data.ljust(5 * ((len(binary_data) // 5) + 1), "0") b32_chunks = map("".join, zip(*[iter(binary_data)] * 5)) - b32_result = "".join(j for j in map(lambda _s: B32_CHARSET[int(_s, 2)], b32_chunks)) + b32_result = "".join( + j for j in [B32_CHARSET[int(chunk, 2)] for chunk in b32_chunks] + ) return bytes(b32_result.ljust(8 * ((len(b32_result) // 8) + 1), "="), "utf-8") @@ -32,13 +34,13 @@ def base32_decode(data: bytes) -> bytes: b'some long complex string' """ binary_chunks = "".join( - map( - lambda _d: bin(B32_CHARSET.index(_d))[2:].zfill(5), - data.decode("utf-8").strip("="), - ) + [ + bin(B32_CHARSET.index(_d))[2:].zfill(5) + for _d in data.decode("utf-8").strip("=") + ] ) binary_data = list(map("".join, zip(*[iter(binary_chunks)] * 8))) - return bytes("".join(list(map(lambda _d: chr(int(_d, 2)), binary_data))), "utf-8") + return bytes("".join([chr(int(_d, 2)) for _d in binary_data]), "utf-8") if __name__ == "__main__": From 89e2c4be6427840b8055a57b5d8fb984549f313f Mon Sep 17 00:00:00 2001 From: Chris O <46587501+ChrisO345@users.noreply.github.com> Date: Sun, 24 Sep 2023 19:04:13 +1300 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Tianyi Zheng --- ciphers/base32.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ciphers/base32.py b/ciphers/base32.py index d298b76c1a24..1924d1e185d7 100644 --- a/ciphers/base32.py +++ b/ciphers/base32.py @@ -15,12 +15,10 @@ def base32_encode(data: bytes) -> bytes: >>> base32_encode(b"some long complex string") b'ONXW2ZJANRXW4ZZAMNXW24DMMV4CA43UOJUW4ZY=' """ - binary_data = "".join([bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")]) + binary_data = "".join(bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")) binary_data = binary_data.ljust(5 * ((len(binary_data) // 5) + 1), "0") b32_chunks = map("".join, zip(*[iter(binary_data)] * 5)) - b32_result = "".join( - j for j in [B32_CHARSET[int(chunk, 2)] for chunk in b32_chunks] - ) + b32_result = "".join(B32_CHARSET[int(chunk, 2)] for chunk in b32_chunks) return bytes(b32_result.ljust(8 * ((len(b32_result) // 8) + 1), "="), "utf-8") @@ -34,10 +32,8 @@ def base32_decode(data: bytes) -> bytes: b'some long complex string' """ binary_chunks = "".join( - [ - bin(B32_CHARSET.index(_d))[2:].zfill(5) - for _d in data.decode("utf-8").strip("=") - ] + bin(B32_CHARSET.index(_d))[2:].zfill(5) + for _d in data.decode("utf-8").strip("=") ) binary_data = list(map("".join, zip(*[iter(binary_chunks)] * 8))) return bytes("".join([chr(int(_d, 2)) for _d in binary_data]), "utf-8")