Implementing Rail-fence Cipher in Python
In today’s tutorial, we will be Implementing Rail-fence Cipher in Python. Rail- fence cipher is a transposition cipher that encrypts the plain text by changing the position of each character.
Let’s first see what Rail-fence cipher actually does.
This cipher takes an input string and a key and arranges the letters in the string in a diagonal fashion. For implementing Rail-fence Cipher in Python, a rectangular grid is required with the number of rows corresponding to the key, and the number of columns corresponding to the length of string to be encrypted. Then the ciphertext is generated by reading the resultant grid row by row.
For example:
Here, The number of rows in the grid = key = 4
The number of columns in the grid= length of plain text = 10
So let’s see the implementation now.
Getting our inputs:
To start off, we’ll need an input string from the user. This will act as our plain text.
Also, we’ll need a key to encrypt our plain text. The key decides the number of rows in the grid.
s=input("Enter string: ") k=int(input("Enter key: "))
Output:
Enter string: CodeSpeedy Enter key: 4
Creating the grid:
To create the grid for our encryption process, we are using a blank list. You can also use NumPy arrays, but for simplicity, we have used lists here. The size of the list as mentioned above will be “the value of key” * “length of the string”. To initialize the list, we first fill the list with ‘ ‘(single space).
enc=[[" " for i in range(len(s))] for j in range(k)] print(enc)
Here we used list comprehension for initializing the list. Note that the size of the list is also defined along with the value initialization.
Let’s see how our grid looks like.
Output:
[[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']]
Thus a blank list of size 4*10 is created.
Putting characters into the grid:
Now, as we saw earlier, the first character is put in the first box of the grid ie. (0,0). Then the following characters are put diagonally in the downward direction. Once it reaches any extremity of the grid, ie. first or last row, it changes its direction and continues in the opposite direction.
So we define a ‘row’ variable to determine which row to add our character to. Along with this, we also define a condition variable ‘flag’ which determines whether we should travel in an upward or a downward direction. Initially, both row and flag will be 0.
flag=0 row=0
The next step is to parse through all the characters in the plain text and determine its position in the grid.
The character index will be the same as the column number in the grid. So we only need to determine the row number now. If flag=0, then we need to continue in the downward direction, and if flag=1, then travel in an upward direction. So, if flag=0, increment row number, and if flag=1, decrement row number. We also need a condition to change the value of flags. So, if the row number of the current character is 0, the flag will be 0, and if the row number is Key-1 ie. the last row, the flag will be 1.
for i in range(len(s)): enc[row][i]=s[i] if row==0: flag=0 elif row==k-1: flag=1 if flag==0: row+=1 else: row-=1
Printing our grid:
At this point, we have filled in our plaintext characters into our grid. Now, let’s check if they are in the right position. For this, we use the join() function which will convert our list to a string.
for i in range(k): print("".join(enc[i]))
Output:
C e o p e d S d e y
Voila! Our railfence is perfect!
Getting our CipherText:
For getting the ciphertext, we need to read our grid row by row and eliminate the spaces between each letter in a row.
To do this, we will parse through each character in every row and append all the characters, which are not spaces, to an initially empty list.
ct=[] for i in range(k): for j in range(len(s)): if enc[i][j]!=' ': ct.append(enc[i][j])
Now convert our ‘ct’ list to string and that’s it! We got our ciphertext.
cipher="".join(ct) print("Cipher Text: ",cipher)
Output:
Cipher Text: CeopedSdey
Although rail-fence cipher is easy to crack, it is generally used in combination with other ciphers like a substitution cipher to make it safer.
Also read:
KNN Classification using Scikit-Learn in Python
Mouse Automation in Python using PyAutoGUI
please make one article on decryption as well.
Great work, Thank you
The Decryption method taken from geeksforgeeks
def decryptRailFence(cipher, key):
rail = [[‘\n’ for i in range(len(cipher))]
for j in range(key)]
dir_down = None
row, col = 0, 0
for i in range(len(cipher)):
if row == 0:
dir_down = True
if row == key – 1:
dir_down = False
rail[row][col] = ‘*’
col += 1
if dir_down:
row += 1
else:
row -= 1
index = 0
for i in range(key):
for j in range(len(cipher)):
if ((rail[i][j] == ‘*’) and
(index < len(cipher))):
rail[i][j] = cipher[index]
index += 1
result = []
row, col = 0, 0
for i in range(len(cipher)):
if row == 0:
dir_down = True
if row == key-1:
dir_down = False
if (rail[row][col] != '*'):
result.append(rail[row][col])
col += 1
if dir_down:
row += 1
else:
row -= 1
return("".join(result))
if __name__ == "__main__":
print(decryptRailFence("CeopedSdey", 4))