Overview

Today we are going to explore another ancient cipher. Relax, I am not planing to turn this blog into a history class. The objective of the blog is to teach you how to encrypt and decrypt a text using the cipher. The cipher we are going to explore today is a transposition cipher. Transposition ciphers are all about confusion. The letters of the plaintext are rearranged in order to create a new different text. The rearrangement of the letters is usually done using a pattern which is easy to follow. This is normally done using a key to jumble the letters of a plaintext so that it becomes unreadable. That’s the aim of it. To leave you totally bemused. Our cipher of the day is called rail fence. Let’s get to it.

Rail Fence Cipher

This cipher is quite easy to grasp, it works by writing the plaintext on a table in a zigzag pattern then read the message row by row going from the left to the right. The number of rows that a table will have is equal to the encryption key. Each time when we loop through the plaintext, the first letter of the alphabet will be place in the first row, the second letter will be allocated to the second row and so on until we get to the last row then go up and down again until you finish off the complete plaintext in a zigzag pattern. Simple right ? I thought as much.

Arrow functions

We are going to use arrow functions to create values and functions that will be used to encrypt and decrypt our messages. I love arrow functions because they are elegant and helps me keep my code clean. Below is just a skeleton of what an arrow function looks like:

(params) => { expressions }

Arrow functions are cool because:

If the function has only one parameter and not using destructuring, you can omit parenthesis. If the function has only one expression, you can can omit braces and its value is returned without using return keyword.

You can learn more about arrow functions over here. Now create a new file and name it railfence.js. Inside it add the following helper functions which we will use for our encryption and decryption.

const createArray = key => {

let array = []

array.length = key

array.fill('')

return array

} const createTable = (text, key) => {

let table = []

for (let index = 0; index < key; index++) {

table[index] = []

}

table.map(row => {

row.length = text.length

row.fill('')

return row

})

return table

} const getDirection = (direction, row, key) => {

if (row === (key - 1)) {

direction = false

} else if (row === 0 || row === -1) {

direction = true

}

return direction

} const currentRow = (direction, row) => direction ? row + 1 : row - 1 const inValidKey = key => key === 0 || key === 1

Functions are first class citizens in the js world. We can do all sort of things with them. We can also use them as values. The first function is for creating an array with empty strings, the second one is for creating a table, the third function is for setting the direction of the loop and lastly inValidKey is a boolean for whether the key is valid or not.

Encrypt function

The purpose of the function is to take in a text and key, then after that it will encrypt the text with the key provided and return the ciphertext.

const encrypt = (text, key) => {

if (inValidKey(key)) {

return "You can't use 0 or 1 as a key"

}

let lettersArray = createArray(key)

let row = -1

let ciphertext

let goingDown = true

for (let letter of text) {

goingDown = getDirection(goingDown, row, key)

row = currentRow(goingDown, row)

lettersArray[row] = lettersArray[row] + letter

}

ciphertext = lettersArray.join('')

return ciphertext

}

Lets go through the code:

We firstly check if the key provided is valid or not using a function called inValidKey and also alert the user if the key is invalid. Then we declare all the necessary variables. Take note of the variable called lettersArray which is an array with empty strings inside it. Each string act as a row of a table where text can be allocated. Allocate each letter of the plaintext to the strings inside the lettersArray starting from the first string to the last one and repeat the process until get back to the first string and so on. Get ciphertext by merging the strings together. Return the ciphertext.

Decrypt function

To decrypt a rail fence cipher is a bit complex. We need to draw a proper table with rows equal to the key and columns equal to the length of our ciphertext. This will allow us to fill in the X and which will represent place holders for the letters of our plaintext. After that we are going to loop throw our ciphertext and allocate all the letters to columns that are marked with X from the first row going down. Then we read the whole table in a zigzag pattern from the left to the right.

const decrypt = (text, key) => { if (inValidKey(key)) {

return "You can't use 0 or 1 as a key"

} let row = -1

let rail = -1

let col = 0

let goingDown = true

let goingSideWay = true

let plaintext = '' let table = createTable(text, key) for (let index in text) {

goingDown = getDirection(goingDown, row, key)

row = goingDown ? row + 1 : row - 1

let array = table[row]

array[index] = 'X'

} table.map(row => {

for (let a = 0; a < row.length; a++) {

if (row[a] === 'X') {

row[a] = text.charAt(col)

col++

}

}

}) for (var i = 0; i < text.length; i++) {

goingSideWay = getDirection(goingSideWay, rail, key)

rail = currentRow(goingSideWay, rail)

let arr = table[rail]

plaintext = plaintext + arr[i]

} return plaintext }

Let’s go through the code:

Mandatory check. We need to make sure that the key provided is not 0 or 1 as usual. After that, we declare all the necessary variables that we will need. We also create a table with row equal to our key and columns equal to the ciphertext using one of the helper function called createTable. For each letter of the ciphertext, allocate an X into a column using a zigzag pattern. For example the first X will be allocated to the first column of the first row. The second X will be allocated to the second column of the second row and so on. We are now going to loop through each row of the table. If the column has an X, we will replace the X with a letter. Lastly we need to read the plaintext from the table that we created. We will read the message from the first row moving down to the rows below it and repeat the process until the last column of the table. Return the plaintext.

Let’s take our functions for a ride so inside the file add the following code below the decrypt function.

let plainText = encrypt("I am feeling lucky today!", 2)

console.log(plainText)

let cipherText = decrypt(plainText,2)

console.log(cipherText)

On your console, run node railfence.js.

$ node railfence.js

Ia eln uk oa! mfeiglcytdy

I am feeling lucky today!

The first text below our command is our ciphertext, as you can see that the second one is the plaintext that we got when we decrypted using our decrypt function. Bravo, you can now encrypt and decrypt a text using rail fence cipher. I know that this blog was a big long, but I am sure that you are going to learn a lot from it.

I hope you gained something from this. That’s all for today!