Ciphers

Porta

Thirteen tables for 26 key letters. A to M always swaps with N to Z. One call encodes and decodes.
IDporta09 / 62classical · polyalphabetic
Cipher / Polyalphabetic

Porta

Thirteen tables, each one trades the halves of A-Z.

Keyspace
13^keyLength
Decode
self-inverse
Works on
A-Z, the rest passes
Family
9 in polyalphabetic
required 1 / 2

Options

keystring
required
Repeating keyword, case-insensitive; A and B pick the same table, and so on up to Y and Z
rotationstring
default left
Which way the N-Z half turns from table to table: left as the ACA prints it, right as dCode does by default

Access

Createcreate("porta")
CLIciphers encode porta 'DEFEND THE EAST WALL' --key FORTIFICATION
Tryplayground with the sample above
Kinvigenere, gronsfeld, beaufort, autokey +4

Giambattista della Porta printed this one in 1563. Each key letter picks one of 13 tables. A and B share the first, C and D the second, and so on up to Y and Z. Every table swaps the two halves of the alphabet. A to M goes to N to Z and back again. So encode and decode are the same call, like Beaufort.

ts
const porta = create("porta");
const key = { key: "FORTIFICATION" };
porta.encode("DEFENDTHEEASTWALLOFTHECASTLE", key).text;
// "SYNNJSCVRNRLAHUTUKUCVRYRLANY"
porta.encode("SYNNJSCVRN", key).text; // "DEFENDTHEE", same call back

That's the worked example from Practical Cryptography, which uses the ACA table.

Which way does it turn?

Here's the catch. Nobody agrees which way the N to Z half moves from table to table. The ACA, Gaines and Practical Cryptography turn it left, so C and D give OPQ…. dCode turns it right by default, so C and D give ZNO…. Same key, same text, two ciphertexts. Both stay reciprocal, so the wrong one doesn't fail. It just hands you noise.

rotation picks the side, left by default or right:

ts
porta.encode("DCODE", { key: "PORTA", rotation: "right" }).text; // "WVJUR", dCode's example
porta.encode("DCODE", { key: "PORTA" }).text; // "XWGZR", the ACA table

Got a Porta from dCode that reads like soup? Flip rotation before you blame the key.

The rest of the text

Only ASCII letters move the key along. Spaces, punctuation and emoji pass through. Lowercase stays lowercase unless preserveCase is false, and stripNonAlpha drops everything outside A to Z first. The key ignores case and anything that isn't a letter. No key is a MissingOptionError, and a key without letters an InvalidOptionError.

Why it's weak

Thirteen tables, not 26. F and E pick the same one, so FORT and EPQS are the same key. A key of n letters has 2^n spellings, and FORTIFICATION alone has 8,192.

Worse, a letter never stays in its half. E can't come out as H, so HEP is never THE. That's a free filter for every crib you try. The key still repeats too, so period finds its length the same way it does for Vigenère. Handy on paper, one table for both ways. That's about all it has going for it.