The rail fence cipher is a transposition cipher in classical cryptography. It is very easy to crack, and provides basically no security.

The cipher

The keyspace of the cipher is a single number that should be smaller than the message size. Common key values are between 3 to 5 characters for short messages.

Encryption

In the rail fence cipher, the plain text is written on K rails in a zig-zag pattern. To see what the pattern looks like, let’s write RailFenceCipher.

Out:
 R . . . . . n . . . . . h . .
 . a . . . e . c . . . p . e .
 . . i . F . . . e . i . . . r
 . . . l . . . . . C . . . . .

In order to turn this into the ciphertext, you read the letters left-to-right, top-to-bottom.

Rnh aecpe iFeir lC

Or in the more traditional ciphertext formatting.

RNHAE CPEIF EIRLC

Encryption like an adult

There is a more practical way to encrypt data with this cipher.

  1. Pick a key K.
  2. Expand K into a sequence of numbers going up and down. The sequence should be as long as the length of our plaintext.
    • For K = 3, that would become 123212321232123....
    • For K = 4, it would be 1234321234321234....
  3. Take the first letter of the plaintext and the first number of our expanded key.
Out:
plaintext = GREETINGS
K = 3, expanded into 123212321

Rail 1:   G Rail 2:      Rail 3:    
Rail 1:   G Rail 2:    R Rail 3:    
Rail 1:   G Rail 2:    R Rail 3:  E 
Rail 1:   G Rail 2:   RE Rail 3:  E 
Rail 1:  GT Rail 2:   RE Rail 3:  E 
Rail 1:  GT Rail 2:  REI Rail 3:  E 
Rail 1:  GT Rail 2:  REI Rail 3: EN 
Rail 1:  GT Rail 2: REIG Rail 3: EN 
Rail 1: GTS Rail 2: REIG Rail 3: EN 

Ciphertext = GTSREIGEN

Decryption

In [4]:
encode_diagram(list(range(15)), 4)
Out:
 0 . . . . . 6 . . . . . 12 . .
 . 1 . . . 5 . 7 . . . 11 . 13 .
 . . 2 . 4 . . . 8 . 10 . . . 14
 . . . 3 . . . . . 9 . . . . .

Example

Let’s try to encrypt the plaintext YELLOWSUBMARINE with three rails. Following the description of the cipher, we end up with.

Out:
 Y . . . O . . . B . . . I . .
 . E . L . W . U . M . R . N .
 . . L . . . S . . . A . . . E

And then read the letters from left-to-right, top-to-bottom. The resulting ciphertext is

YOBIE LWUMR NLSAE

Decoding

In [6]:
ciphertext = "YOBIELWUMRNLSAE"
key = 3

plaintext = [" " for _ in range(len(ciphertext))]

d = decoder(len(ciphertext), key)
for i, index in enumerate(d):
    plaintext[index] = ciphertext[i]

"".join(plaintext)
Out [6]:
'YELLOWSUBMARINE'

Useful links