From 7a4647a8a51ba542f3a659ce29940a56233bba0a Mon Sep 17 00:00:00 2001
From: Chris O <46587501+ChrisO345@users.noreply.github.com>
Date: Wed, 20 Sep 2023 14:44:27 +1200
Subject: [PATCH 1/3] rewrite of base85.py

---
 ciphers/base85.py | 62 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 46 insertions(+), 16 deletions(-)

diff --git a/ciphers/base85.py b/ciphers/base85.py
index afd1aff79d11..b0082f3871c0 100644
--- a/ciphers/base85.py
+++ b/ciphers/base85.py
@@ -1,30 +1,60 @@
-import base64
+"""
+Base85 (Ascii85) encoding and decoding
 
+https://en.wikipedia.org/wiki/Ascii85
+"""
 
-def base85_encode(string: str) -> bytes:
+
+def _base10_to_85(d: int) -> str:
+    return "".join(chr(d % 85 + 33)) + _base10_to_85(d // 85) if d > 0 else ""
+
+
+def _base85_to_10(digits: list) -> int:
+    return sum(char * 85**i for i, char in enumerate(digits[::-1]))
+
+
+def ascii85_encode(data: bytes) -> bytes:
     """
-    >>> base85_encode("")
+    >>> ascii85_encode(b"")
     b''
-    >>> base85_encode("12345")
+    >>> ascii85_encode(b"12345")
     b'0etOA2#'
-    >>> base85_encode("base 85")
+    >>> ascii85_encode(b"base 85")
     b'@UX=h+?24'
     """
-    # encoded the input to a bytes-like object and then a85encode that
-    return base64.a85encode(string.encode("utf-8"))
+    binary_data = "".join([bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")])
+    null_values = (32 * ((len(binary_data) // 32) + 1) - len(binary_data)) // 8
+    binary_data = binary_data.ljust(32 * ((len(binary_data) // 32) + 1), "0")
+    b85_chunks = map(
+        lambda _s: int(_s, 2), map("".join, zip(*[iter(binary_data)] * 32))
+    )
+    result = "".join(
+        item for item in list(map(lambda chunk: _base10_to_85(chunk)[::-1], b85_chunks))
+    )
+    return bytes(result[:-null_values] if null_values % 4 != 0 else result, "utf-8")
 
 
-def base85_decode(a85encoded: bytes) -> str:
+def ascii85_decode(data: bytes) -> bytes:
     """
-    >>> base85_decode(b"")
-    ''
-    >>> base85_decode(b"0etOA2#")
-    '12345'
-    >>> base85_decode(b"@UX=h+?24")
-    'base 85'
+    >>> ascii85_decode(b"")
+    b''
+    >>> ascii85_decode(b"0etOA2#")
+    b'12345'
+    >>> ascii85_decode(b"@UX=h+?24")
+    b'base 85'
     """
-    # a85decode the input into bytes and decode that into a human readable string
-    return base64.a85decode(a85encoded).decode("utf-8")
+    null_values = 5 * ((len(data) // 5) + 1) - len(data)
+    binary_data = data.decode("utf-8") + "u" * null_values
+    b85_chunks = map("".join, zip(*[iter(binary_data)] * 5))
+    b85_segments = [list(map(lambda _s: ord(_s) - 33, chunk)) for chunk in b85_chunks]
+    results = [(bin(_base85_to_10(chunk))[2::].zfill(32)) for chunk in b85_segments]
+    char_chunks = [
+        list(map(lambda _s: chr(int(_s, 2)), map("".join, zip(*[iter(r)] * 8))))
+        for r in results
+    ]
+    result = "".join("".join(char) for char in char_chunks)
+    offset = 0 if null_values % 5 != 0 else 1
+    return bytes(result[: -null_values + offset], "utf-8")
 
 
 if __name__ == "__main__":

From dbf12b78fdbe333aa54feb2309fcceb2bdf83d34 Mon Sep 17 00:00:00 2001
From: Chris O <46587501+ChrisO345@users.noreply.github.com>
Date: Wed, 20 Sep 2023 15:12:03 +1200
Subject: [PATCH 2/3] changed maps to list comprehension

---
 ciphers/base85.py | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/ciphers/base85.py b/ciphers/base85.py
index b0082f3871c0..e11d6c4db8c9 100644
--- a/ciphers/base85.py
+++ b/ciphers/base85.py
@@ -25,11 +25,9 @@ def ascii85_encode(data: bytes) -> bytes:
     binary_data = "".join([bin(ord(d))[2:].zfill(8) for d in data.decode("utf-8")])
     null_values = (32 * ((len(binary_data) // 32) + 1) - len(binary_data)) // 8
     binary_data = binary_data.ljust(32 * ((len(binary_data) // 32) + 1), "0")
-    b85_chunks = map(
-        lambda _s: int(_s, 2), map("".join, zip(*[iter(binary_data)] * 32))
-    )
+    b85_chunks = [int(_s, 2) for _s in map("".join, zip(*[iter(binary_data)] * 32))]
     result = "".join(
-        item for item in list(map(lambda chunk: _base10_to_85(chunk)[::-1], b85_chunks))
+        item for item in [_base10_to_85(chunk)[::-1] for chunk in b85_chunks]
     )
     return bytes(result[:-null_values] if null_values % 4 != 0 else result, "utf-8")
 
@@ -46,11 +44,10 @@ def ascii85_decode(data: bytes) -> bytes:
     null_values = 5 * ((len(data) // 5) + 1) - len(data)
     binary_data = data.decode("utf-8") + "u" * null_values
     b85_chunks = map("".join, zip(*[iter(binary_data)] * 5))
-    b85_segments = [list(map(lambda _s: ord(_s) - 33, chunk)) for chunk in b85_chunks]
+    b85_segments = [[ord(_s) - 33 for _s in chunk] for chunk in b85_chunks]
     results = [(bin(_base85_to_10(chunk))[2::].zfill(32)) for chunk in b85_segments]
     char_chunks = [
-        list(map(lambda _s: chr(int(_s, 2)), map("".join, zip(*[iter(r)] * 8))))
-        for r in results
+        [chr(int(_s, 2)) for _s in map("".join, zip(*[iter(r)] * 8))] for r in results
     ]
     result = "".join("".join(char) for char in char_chunks)
     offset = 0 if null_values % 5 != 0 else 1

From 2a2015e4ad1da698d6116fc7a5d7a2936484ac7d Mon Sep 17 00:00:00 2001
From: Chris O <46587501+ChrisO345@users.noreply.github.com>
Date: Sun, 24 Sep 2023 19:10:31 +1300
Subject: [PATCH 3/3] Apply suggestions from code review

Co-authored-by: Tianyi Zheng <tianyizheng02@gmail.com>
---
 ciphers/base85.py | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/ciphers/base85.py b/ciphers/base85.py
index e11d6c4db8c9..f0228e5052dd 100644
--- a/ciphers/base85.py
+++ b/ciphers/base85.py
@@ -10,7 +10,7 @@ def _base10_to_85(d: int) -> str:
 
 
 def _base85_to_10(digits: list) -> int:
-    return sum(char * 85**i for i, char in enumerate(digits[::-1]))
+    return sum(char * 85**i for i, char in enumerate(reversed(digits)))
 
 
 def ascii85_encode(data: bytes) -> bytes:
@@ -22,13 +22,11 @@ def ascii85_encode(data: bytes) -> bytes:
     >>> ascii85_encode(b"base 85")
     b'@UX=h+?24'
     """
-    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"))
     null_values = (32 * ((len(binary_data) // 32) + 1) - len(binary_data)) // 8
     binary_data = binary_data.ljust(32 * ((len(binary_data) // 32) + 1), "0")
     b85_chunks = [int(_s, 2) for _s in map("".join, zip(*[iter(binary_data)] * 32))]
-    result = "".join(
-        item for item in [_base10_to_85(chunk)[::-1] for chunk in b85_chunks]
-    )
+    result = "".join(_base10_to_85(chunk)[::-1] for chunk in b85_chunks)
     return bytes(result[:-null_values] if null_values % 4 != 0 else result, "utf-8")
 
 
@@ -45,13 +43,13 @@ def ascii85_decode(data: bytes) -> bytes:
     binary_data = data.decode("utf-8") + "u" * null_values
     b85_chunks = map("".join, zip(*[iter(binary_data)] * 5))
     b85_segments = [[ord(_s) - 33 for _s in chunk] for chunk in b85_chunks]
-    results = [(bin(_base85_to_10(chunk))[2::].zfill(32)) for chunk in b85_segments]
+    results = [bin(_base85_to_10(chunk))[2::].zfill(32) for chunk in b85_segments]
     char_chunks = [
         [chr(int(_s, 2)) for _s in map("".join, zip(*[iter(r)] * 8))] for r in results
     ]
     result = "".join("".join(char) for char in char_chunks)
-    offset = 0 if null_values % 5 != 0 else 1
-    return bytes(result[: -null_values + offset], "utf-8")
+    offset = int(null_values % 5 == 0)
+    return bytes(result[: offset - null_values], "utf-8")
 
 
 if __name__ == "__main__":