Ciphers

Columnar transposition

The text fills rows under a keyword, columns are read out in the keyword's alphabetical order. Whitespace survives the round trip.
IDcolumnar33 / 72classical · transposition
Cipher / Transposition

Columnar Transposition

Rows in, columns out in keyword order.

Keyspace
n!
Decode
same options back
Works on
all characters, moved
Family
3 in transposition
required 1 / 1

Options

keystring
required
Keyword determining column order

Access

Createcreate("columnar")
CLIciphers encode columnar 'ATTACK AT DAWN' --key ZEBRA
Tryplayground with the sample above
Kinrail-fence, route

The keyword's letters number the columns by alphabetical order, the text fills the grid row by row, and the ciphertext is the columns read in that order. Every character is a cell, spaces too, so decode(encode(x)) is x for any input. Textbook vectors drop the spaces and punctuation before filling the grid, and stripNonAlpha: true does that for you. key is required.

ts
const columnar = create("columnar");
columnar.encode("ATTACK AT DAWN", { key: "ZEBRA" }).text; // "C TAWT AATNAKD"
columnar.decode("C TAWT AATNAKD", { key: "ZEBRA" }).text; // "ATTACK AT DAWN"
columnar.encode("WE ARE DISCOVERED. FLEE AT ONCE", { key: "ZEBRAS", stripNonAlpha: true }).text; // "EVLNACDTESEAROFODEECWIREE"

Repeated letters in the key are ordered left to right. This is also the second step of the historical ADFGVX.

Columnar is the one cipher with state. The instance keeps an LRU cache of its last 128 answers, so asking the same thing twice costs nothing. Nothing caps how often you call it, which matters when a loop tries thousands of candidate keys.