Two-square
Two-square
Letter pairs across two keyed squares, one in five left alone.
- Keyspace
- (25!)² ≈ 2.4×10⁵⁰
- Decode
- same options back
- Works on
- A-Z in pairs, J as I (or Q dropped), X pads an odd length, the rest dropped
- Family
- 3 in digraph
Options
Access
- Create
create("two-square") - CLI
ciphers encode two-square 'HELP ME OBI WAN KENOBI' --key EXAMPLE --second-key KEYWORD - Tryplayground with the sample above
- Kinplayfair, four-square
Four-square with the plain squares thrown out. Delastelle put it in the same book and called it a reduced digraphic checkerboard, which is a very French way to say "two squares". Find the first letter of a pair in one square, the second in the other. The rectangle they span gives the ciphertext. Half the drawing, and a leak to match.
const twoSquare = create("two-square");
const keys = { key: "EXAMPLE", secondKey: "KEYWORD", omit: "q" };
twoSquare.encode("help me obi wan kenobi", keys).text; // "HEDLXWSDJYANHOTKDG"
twoSquare.decode("HEDLXWSDJYANHOTKDG", keys).text; // "HELPMEOBIWANKENOBI"
That's the example on Wikipedia. Look at the first pair. HE went in, HE came out. AN too. Not a bug, that's the cipher.
Why do pairs slip through?
By default the squares are stacked, key on top and secondKey below. Each letter comes back from its own square, on its own row, in the other letter's column. Now put both letters in one column. The other letter's column is the same one, so nothing moves. Random squares do that to about one pair in five.
Decoding is the same step here. Encode the ciphertext again and you get the plaintext back.
Side by side
orientation: "horizontal" puts key on the left and secondKey on the right. The ACA prints it that way, and dCode starts there too. The rectangle now crosses from one square into the other, so each letter's partner lives in the other square. A pair in one row comes out reversed.
const aca = { key: "DIALOGUE", secondKey: "BIOGRAPHY", orientation: "horizontal" };
twoSquare.encode("another digraphic setup", aca).text;
// "IRRTEHMKGIMEQGRUNMMZSV"
That's the ACA's own example. See the EH in the middle? It's he, read backwards. The dCode one works the same way: CDLBAV under KEY and WORD decodes to DCODEZ.
Side by side, decoding isn't encoding anymore. Run encode twice and you get mush. So say which way you're going.
Crypto Corner sets its squares side by side too, but trades rows where the ACA and dCode trade columns. Its horizontal ciphertext won't match, and no option here bends to it. Its stacked one does: HECMXWSRKYXPHWNODG, with I and J sharing a cell.
J or Q?
Same deal as four-square. J folds into I by default. omit: "q" drops Q from the squares, the keywords and the text, which is what the Wikipedia example needs. The result options carry orientation and omit only when they aren't the default.
The text loses everything but letters and comes out in capitals. An odd length gets an X, and a doubled pair stays doubled. Ciphertext with an odd number of letters is a CipherError. Both keywords are required, and each needs at least one ASCII letter.
Spotting one
From a distance it's four-square. Even count, no J, doubled pairs allowed. Up close, some pairs read like English. guess scores the pairs at even positions against English, straight and reversed. When they read better than a four-square leaves them, two-square moves ahead and the signal names the layout.
How good is that? Honestly, meh. At 100 letters it catches about half of them, at 400 about seven in ten. A four-square fools it about one time in eight. Only English has a pair table, and squares without Q put J back in the text, so guess misses those.
Want to do it by hand? Write the ciphertext in pairs and just read. TH and HE sitting on pair boundaries are a two-square getting lazy. Nothing there? Flip every pair and read again.