otp.py
Wrote a small decoder tonight, for when (if) I ever get Band II.
A one-time pad is simple. Ciphertext minus key, digit by digit, mod 10. Then read the result in pairs and turn each pair into a letter. I used the dumbest possible table: 01 is A, 26 is Z, 00 is a space. Anything else comes out as a question mark.
# otp.py - one-time pad decoder for number tables
# usage: python3 otp.py CIPHER_DIGITS KEY_DIGITS
import sys
TABLE = {"00": " "}
TABLE.update({f"{i:02d}": chr(64 + i) for i in range(1, 27)})
def decode(cipher, key):
digits = "".join(str((int(c) - int(k)) % 10) for c, k in zip(cipher, key))
pairs = [digits[i:i + 2] for i in range(0, len(digits) - 1, 2)]
return "".join(TABLE.get(p, "?") for p in pairs)
if __name__ == "__main__":
cipher = "".join(ch for ch in sys.argv[1] if ch.isdigit())
key = "".join(ch for ch in sys.argv[2] if ch.isdigit())
print(decode(cipher, key))
The only test I can run right now: page 31 with page 117 as the key. They're identical, so everything comes out zero, and it decodes to 625 spaces.
Either a joke or a very long silence.