Substitution
Substitution
One shuffled alphabet, keyed by a word.
- Keyspace
- 26!
- Decode
- same options back
- Works on
- A-Z, the rest passes
- Family
- 1 in mixed alphabet
Options
Access
- Create
create("substitution") - CLI
ciphers encode substitution 'FLEE AT ONCE' --key ZEBRAS - Tryplayground with the sample above
The one from the newspaper puzzle page. Every letter gets one stand-in, and it's the same one every time. Caesar does that too, but Caesar only slides the alphabet. Here the alphabet is shuffled any way you like. That's 26! keys, about 2^88. Nobody tries them all.
The key
key comes in two shapes. Exactly 26 letters is a whole cipher alphabet, taken as it is: the first cell is what A becomes, the second is B, and so on. Each letter shows up once. A repeat is an InvalidOptionError, not a quiet keyword with some other mapping. Anything else is a keyword. Its letters go first, repeats dropped, then the rest of A to Z in order. So ZEBRAS turns into ZEBRASCDFGHIJKLMNOPQTUVWXY, and that's Wikipedia's example:
const substitution = create("substitution");
substitution.encode("FLEE AT ONCE. WE ARE DISCOVERED!", { key: "ZEBRAS" }).text; // "SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!"
substitution.decode("SIAA ZQ LKBA. VA ZOA RFPBLUAOAR!", { key: "ZEBRAS" }).text; // "FLEE AT ONCE. WE ARE DISCOVERED!"
Case stays put. Spaces, digits and everything outside A to Z pass through untouched.
A key with holes
What if you only know part of the key? recover solves a substitution from the ciphertext alone. But it can only name letters the text actually uses, and the rest come back as ?. Hand that key straight to decode. A ? cell gives ?, and every letter you do know reads fine:
substitution.encode("Bad", { key: "ZEB?ASCDFGHIJKLMNOPQTUVWXY" }).text; // "Ez?"
substitution.decode("Ez?R", { key: "ZEB?ASCDFGHIJKLMNOPQTUVWXY" }).text; // "Ba??"
A ? only counts in a whole alphabet: 26 cells, each letter at most once. Anywhere else it's an InvalidOptionError. Why so strict? A recovered key that lost a cell on the way would turn into a keyword and shift every letter after the gap. Quietly. No thanks.
Atbash and all 25 Caesar shifts are substitutions too, just with keys you could write down from memory. Counting letters breaks every one of them the same way.