owenrusk.dev

tally

shamir's secret sharing over gf(256).

git clone https://owenrusk.dev/tally.git

commit 894350c029ce52829bb62903262720c00ac1ce86
parent 4f5d31046118b3d4e52147a8cb8aa4ac1dada770
author Owen Rusk <owen@papermothgames.com>
date   2024-06-29 11:20:44 -0500
codec: read o as 0, and i or l as 1
tally/codec.py+2-0
tests/test_codec.py+9-0
diff --git a/tally/codec.py b/tally/codec.py
index aa9f9de..2748170 100644
--- a/tally/codec.py
+++ b/tally/codec.py
@@ -11,6 +11,8 @@ ID_BYTES = 4
 CHECK_BYTES = 4
 
 _VALUES = {c: i for i, c in enumerate(ALPHABET)}
+# read the lookalikes the way a person probably meant them
+_VALUES.update({"o": 0, "i": 1, "l": 1})
 
 
 class ShareError(ValueError):
diff --git a/tests/test_codec.py b/tests/test_codec.py
index cb9c106..214848b 100644
--- a/tests/test_codec.py
+++ b/tests/test_codec.py
@@ -28,6 +28,15 @@ class CodecTest(unittest.TestCase):
         self.assertEqual(codec.decode(text.upper()), SHARE)
         self.assertEqual(codec.decode("  " + text.replace("-", " - ") + "\n"), SHARE)
 
+    def test_lookalikes(self) -> None:
+        text = codec.encode(SHARE)
+        body = text[3:]
+        self.assertTrue("0" in body and "1" in body)
+        mistyped = text[:3] + body.replace("0", "o").replace("1", "l")
+        self.assertEqual(codec.decode(mistyped), SHARE)
+        mistyped = text[:3] + body.replace("1", "i")
+        self.assertEqual(codec.decode(mistyped), SHARE)
+
     def test_not_a_share(self) -> None:
         for text in ["", "hello", "t1", "x1-abcd", "t1-ab", "t1-abcd-u000"]:
             with self.subTest(text=text), self.assertRaises(ShareError):