tally
shamir's secret sharing over gf(256).
git clone https://owenrusk.dev/tally.git
commit eed86d5b4ffb6b8bded85b168a45f131cf16dc27 parent 7f8992f16014e41668a581b9dcf782d314797c34 author Owen Rusk <owen@papermothgames.com> date 2025-09-03 19:55:20 -0500
join: skip blank lines and # comments on stdin
| README.md | +2 | -0 |
| tally/cli.py | +7 | -2 |
| tests/test_cli.py | +8 | -0 |
diff --git a/README.md b/README.md index 6ec20cc..4676c78 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ reads the secret from the file, or from stdin if there's no file, and prints n s takes the shares as arguments, or one per line on stdin, and prints the secret. it refuses fewer than k, the same share twice, and shares from different splits. shares past the first k are checked against them. +on stdin, blank lines and lines starting with `#` are skipped, so a file of shares can carry notes. + ## share format t1-xxxx-xxxx-xxxx-... diff --git a/tally/cli.py b/tally/cli.py index 6b70758..7792b7e 100644 --- a/tally/cli.py +++ b/tally/cli.py @@ -17,9 +17,14 @@ def cmd_split(args: argparse.Namespace) -> int: return 0 +def _stdin_shares() -> list[str]: + # blank lines and # comments are skipped, so a file of shares can carry notes + lines = (line.strip() for line in sys.stdin) + return [line for line in lines if line and not line.startswith("#")] + + def cmd_join(args: argparse.Namespace) -> int:- lines = args.shares or [line for line in sys.stdin if line.strip()]- sys.stdout.buffer.write(join(lines))+ sys.stdout.buffer.write(join(args.shares or _stdin_shares())) return 0 diff --git a/tests/test_cli.py b/tests/test_cli.py index 0e852cc..7dc1bd0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -38,6 +38,14 @@ class CliTest(unittest.TestCase): self.assertEqual(join.returncode, 0, join.stderr) self.assertEqual(join.stdout, secret) + def test_stdin_skips_blanks_and_comments(self) -> None: + split = tally("split", "-k", "2", "-n", "3", stdin=b"not a real secret") + a, _, c = split.stdout.decode().split() + notes = f"# first one\n{a}\n\n # the third\n {c} \n\n".encode() + join = tally("join", stdin=notes) + self.assertEqual(join.returncode, 0, join.stderr) + self.assertEqual(join.stdout, b"not a real secret") + def test_secret_option(self) -> None: split = tally("split", "-k", "2", "-n", "2", "--secret", "not a real secret") join = tally("join", stdin=split.stdout)