From c4374da5ae0994f0ca5e2e243e5577199267d985 Mon Sep 17 00:00:00 2001
From: Scott Worley <scottworley@scottworley.com>
Date: Wed, 14 Feb 2024 22:59:23 -0800
Subject: [PATCH] decode support

---
 rfc1751.py      | 15 +++++++++++++--
 rfc1751_test.py | 22 +++++++++++++---------
 tests/decode.sh |  7 +++++++
 tests/encode.sh |  1 +
 4 files changed, 34 insertions(+), 11 deletions(-)
 create mode 100755 tests/decode.sh

diff --git a/rfc1751.py b/rfc1751.py
index 70bae6e..70f5b3a 100644
--- a/rfc1751.py
+++ b/rfc1751.py
@@ -18,7 +18,8 @@ import sys
 from rfc1751wordlist import WORD_LIST, WORD_LIST_SIZE
 
 
-# TODO: Decode
+WORD_LIST_INVERTED = {word: i for (i, word) in enumerate(WORD_LIST)}
+assert len(WORD_LIST_INVERTED) == WORD_LIST_SIZE
 
 
 def encode_actual(x: int) -> list[str]:
@@ -30,8 +31,18 @@ def encode(x: int) -> list[str]:
     return [WORD_LIST[x]] if x == 0 else encode_actual(x)
 
 
+def decode(x: list[str]) -> int:
+    return WORD_LIST_SIZE * decode(x[:-1]) + \
+        WORD_LIST_INVERTED[x[-1]] if x else 0
+
+
 def main() -> None:
-    print(' '.join(encode(int(sys.argv[1]))))
+    if sys.argv[1].isnumeric():
+        print(' '.join(encode(int(sys.argv[1]))))
+    elif len(sys.argv) == 2:
+        print(decode(sys.argv[1].split(' ')))
+    else:
+        print(decode(sys.argv[1:]))
 
 
 if __name__ == '__main__':
diff --git a/rfc1751_test.py b/rfc1751_test.py
index 9999dac..a272e89 100644
--- a/rfc1751_test.py
+++ b/rfc1751_test.py
@@ -15,21 +15,25 @@
 
 import unittest
 
-from rfc1751 import encode
+from rfc1751 import encode, decode
 
 
 class TestRFC1751(unittest.TestCase):
+    def check(self, num: int, words: list[str]) -> None:
+        self.assertEqual(encode(num), words)
+        self.assertEqual(decode(words), num)
+
     def testRFC1751(self) -> None:
-        self.assertEqual(encode(0), ['A'])
-        self.assertEqual(encode(1), ['ABE'])
-        self.assertEqual(encode(2), ['ACE'])
-        self.assertEqual(encode(2047), ['YOKE'])
-        self.assertEqual(encode(2048), ['ABE', 'A'])
-        self.assertEqual(encode(2049), ['ABE', 'ABE'])
-        self.assertEqual(encode(2050), ['ABE', 'ACE'])
+        self.check(0, ['A'])
+        self.check(1, ['ABE'])
+        self.check(2, ['ACE'])
+        self.check(2047, ['YOKE'])
+        self.check(2048, ['ABE', 'A'])
+        self.check(2049, ['ABE', 'ABE'])
+        self.check(2050, ['ABE', 'ACE'])
 
         # Note: These can get NSFW
-        self.assertEqual(encode(2112325), ['FIRM', 'COCK'])
+        self.check(2112325, ['FIRM', 'COCK'])
 
 
 if __name__ == '__main__':
diff --git a/tests/decode.sh b/tests/decode.sh
new file mode 100755
index 0000000..f90fecd
--- /dev/null
+++ b/tests/decode.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+[ "$(python3 rfc1751.py MANY WORD WORK)" = 6148810734 ]
+[ "$(python3 rfc1751.py 'ONE WORD WORK')" = 1597990894 ]
+[ "$(python3 rfc1751.py BIG BIG ONE SO BIG SO SO BIG ONE WORK GOOD WORK REAL GOOD)" = 669350037874937989068749321016845031137563765 ]
diff --git a/tests/encode.sh b/tests/encode.sh
index 03e5e2c..3b146c2 100755
--- a/tests/encode.sh
+++ b/tests/encode.sh
@@ -3,3 +3,4 @@
 set -e
 
 [ "$(python3 rfc1751.py 2937402)" = 'LOVE YOU' ]
+[ "$(python3 rfc1751.py 669350037874937989068749321016845031137563765)" = 'BIG BIG ONE SO BIG SO SO BIG ONE WORK GOOD WORK REAL GOOD' ]
-- 
2.47.2