Open In App

Playfair Cipher with Examples

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

The Playfair cipher was the first practical digraph substitution cipher. The scheme was invented in 1854 by Charles Wheatstone but was named after Lord Playfair who promoted the use of the cipher. In playfair cipher unlike traditional cipher we encrypt a pair of alphabets(digraphs) instead of a single alphabet.
It was used for tactical purposes by British forces in the Second Boer War and in World War I and for the same purpose by the Australians during World War II. This was because Playfair is reasonably fast to use and requires no special equipment.
 

Encryption Technique

For the encryption process let us consider the following example:
 

Encryption Technique

The Playfair Cipher Encryption Algorithm: 
The Algorithm consists of 2 steps: 
 

  1. Generate the key Square(5×5): 
    • The key square is a 5×5 grid of alphabets that acts as the key for encrypting the plaintext. Each of the 25 alphabets must be unique and one letter of the alphabet (usually J) is omitted from the table (as the table can hold only 25 alphabets). If the plaintext contains J, then it is replaced by I. 
       
    • The initial alphabets in the key square are the unique alphabets of the key in the order in which they appear followed by the remaining letters of the alphabet in order. 
       
  2. Algorithm to encrypt the plain text: The plaintext is split into pairs of two letters (digraphs). If there is an odd number of letters, a Z is added to the last letter. 
    For example: 
     
PlainText: "instruments" 
After Split: 'in' 'st' 'ru' 'me' 'nt' 'sz'

1. Pair cannot be made with same letter. Break the letter in single and add a bogus letter to the previous letter.

Plain Text: “hello”

After Split: ‘he’ ‘lx’ ‘lo’

Here ‘x’ is the bogus letter.

2. If the letter is standing alone in the process of pairing, then add an extra bogus letter with the alone letter

Plain Text: “helloe”

AfterSplit: ‘he’ ‘lx’ ‘lo’ ‘ez’

Here ‘z’  is the bogus letter.

Rules for Encryption: 
 

  • If both the letters are in the same column: Take the letter below each one (going back to the top if at the bottom).
    For example: 
     
Diagraph: "me"
Encrypted Text: cl
Encryption:
m -> c
e -> l
  •  

Rules for Encryption 1

  •  
  • If both the letters are in the same row: Take the letter to the right of each one (going back to the leftmost if at the rightmost position).
    For example: 
     
Diagraph: "st"
Encrypted Text: tl
Encryption:
s -> t
t -> l
  •  

Rules for Encryption 2

  •  
  • If neither of the above rules is true: Form a rectangle with the two letters and take the letters on the horizontal opposite corner of the rectangle.
    For example: 
     
Diagraph: "nt"
Encrypted Text: rq
Encryption:
n -> r
t -> q
  •  

Rules for Encryption 3

  •  

For example: 
 

Plain Text: "instrumentsz"
Encrypted Text: gatlmzclrqtx
Encryption:
i -> g
n -> a
s -> t
t -> l
r -> m
u -> z
m -> c
e -> l
n -> r
t -> q
s -> t
z -> x

 

Example of encryption

Below is an implementation of Playfair Cipher in C:
 

C++




// C++ program to implement Playfair Cipher
 
#include <bits/stdc++.h>
using namespace std;
#define SIZE 30
 
// Function to convert the string to lowercase
void toLowerCase(char plain[], int ps)
{
    int i;
    for (i = 0; i < ps; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}
 
// Function to remove all spaces in a string
int removeSpaces(char* plain, int ps)
{
    int i, count = 0;
    for (i = 0; i < ps; i++)
        if (plain[i] != ' ')
            plain[count++] = plain[i];
    plain[count] = '\0';
    return count;
}
 
// Function to generate the 5x5 key square
void generateKeyTable(char key[], int ks, char keyT[5][5])
{
    int i, j, k, flag = 0;
 
    // a 26 character hashmap
    // to store count of the alphabet
    int dicty[26] = { 0 };
    for (i = 0; i < ks; i++) {
        if (key[i] != 'j')
            dicty[key[i] - 97] = 2;
    }
 
    dicty['j' - 97] = 1;
 
    i = 0;
    j = 0;
 
    for (k = 0; k < ks; k++) {
        if (dicty[key[k] - 97] == 2) {
            dicty[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
 
    for (k = 0; k < 26; k++) {
        if (dicty[k] == 0) {
            keyT[i][j] = (char)(k + 97);
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
}
 
// Function to search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
    int i, j;
 
    if (a == 'j')
        a = 'i';
    else if (b == 'j')
        b = 'i';
 
    for (i = 0; i < 5; i++) {
 
        for (j = 0; j < 5; j++) {
 
            if (keyT[i][j] == a) {
                arr[0] = i;
                arr[1] = j;
            }
            else if (keyT[i][j] == b) {
                arr[2] = i;
                arr[3] = j;
            }
        }
    }
}
 
// Function to find the modulus with 5
int mod5(int a) { return (a % 5); }
 
// Function to make the plain text length to be even
int prepare(char str[], int ptrs)
{
    if (ptrs % 2 != 0) {
        str[ptrs++] = 'z';
        str[ptrs] = '\0';
    }
    return ptrs;
}
 
// Function for performing the encryption
void encrypt(char str[], char keyT[5][5], int ps)
{
    int i, a[4];
 
    for (i = 0; i < ps; i += 2) {
 
        search(keyT, str[i], str[i + 1], a);
 
        if (a[0] == a[2]) {
            str[i] = keyT[a[0]][mod5(a[1] + 1)];
            str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];
        }
        else if (a[1] == a[3]) {
            str[i] = keyT[mod5(a[0] + 1)][a[1]];
            str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
        }
        else {
            str[i] = keyT[a[0]][a[3]];
            str[i + 1] = keyT[a[2]][a[1]];
        }
    }
}
 
// Function to encrypt using Playfair Cipher
void encryptByPlayfairCipher(char str[], char key[])
{
    char ps, ks, keyT[5][5];
 
    // Key
    ks = strlen(key);
    ks = removeSpaces(key, ks);
    toLowerCase(key, ks);
 
    // Plaintext
    ps = strlen(str);
    toLowerCase(str, ps);
    ps = removeSpaces(str, ps);
 
    ps = prepare(str, ps);
 
    generateKeyTable(key, ks, keyT);
 
    encrypt(str, keyT, ps);
}
 
// Driver code
int main()
{
    char str[SIZE], key[SIZE];
 
    // Key to be encrypted
    strcpy(key, "Monarchy");
    cout << "Key text: " << key << "\n";
 
    // Plaintext to be encrypted
    strcpy(str, "instruments");
    cout << "Plain text: " << str << "\n";
 
    // encrypt using Playfair Cipher
    encryptByPlayfairCipher(str, key);
 
    cout << "Cipher text: " << str << "\n";
 
    return 0;
}
 
// This code is contributed by aditya942003patil


C




// C program to implement Playfair Cipher
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define SIZE 30
 
// Function to convert the string to lowercase
void toLowerCase(char plain[], int ps)
{
    int i;
    for (i = 0; i < ps; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}
 
// Function to remove all spaces in a string
int removeSpaces(char* plain, int ps)
{
    int i, count = 0;
    for (i = 0; i < ps; i++)
        if (plain[i] != ' ')
            plain[count++] = plain[i];
    plain[count] = '\0';
    return count;
}
 
// Function to generate the 5x5 key square
void generateKeyTable(char key[], int ks, char keyT[5][5])
{
    int i, j, k, flag = 0, *dicty;
 
    // a 26 character hashmap
    // to store count of the alphabet
    dicty = (int*)calloc(26, sizeof(int));
    for (i = 0; i < ks; i++) {
        if (key[i] != 'j')
            dicty[key[i] - 97] = 2;
    }
 
    dicty['j' - 97] = 1;
 
    i = 0;
    j = 0;
 
    for (k = 0; k < ks; k++) {
        if (dicty[key[k] - 97] == 2) {
            dicty[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
 
    for (k = 0; k < 26; k++) {
        if (dicty[k] == 0) {
            keyT[i][j] = (char)(k + 97);
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
}
 
// Function to search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
    int i, j;
 
    if (a == 'j')
        a = 'i';
    else if (b == 'j')
        b = 'i';
 
    for (i = 0; i < 5; i++) {
 
        for (j = 0; j < 5; j++) {
 
            if (keyT[i][j] == a) {
                arr[0] = i;
                arr[1] = j;
            }
            else if (keyT[i][j] == b) {
                arr[2] = i;
                arr[3] = j;
            }
        }
    }
}
 
// Function to find the modulus with 5
int mod5(int a) { return (a % 5); }
 
// Function to make the plain text length to be even
int prepare(char str[], int ptrs)
{
    if (ptrs % 2 != 0) {
        str[ptrs++] = 'z';
        str[ptrs] = '\0';
    }
    return ptrs;
}
 
// Function for performing the encryption
void encrypt(char str[], char keyT[5][5], int ps)
{
    int i, a[4];
 
    for (i = 0; i < ps; i += 2) {
 
        search(keyT, str[i], str[i + 1], a);
 
        if (a[0] == a[2]) {
            str[i] = keyT[a[0]][mod5(a[1] + 1)];
            str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];
        }
        else if (a[1] == a[3]) {
            str[i] = keyT[mod5(a[0] + 1)][a[1]];
            str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
        }
        else {
            str[i] = keyT[a[0]][a[3]];
            str[i + 1] = keyT[a[2]][a[1]];
        }
    }
}
 
// Function to encrypt using Playfair Cipher
void encryptByPlayfairCipher(char str[], char key[])
{
    char ps, ks, keyT[5][5];
 
    // Key
    ks = strlen(key);
    ks = removeSpaces(key, ks);
    toLowerCase(key, ks);
 
    // Plaintext
    ps = strlen(str);
    toLowerCase(str, ps);
    ps = removeSpaces(str, ps);
 
    ps = prepare(str, ps);
 
    generateKeyTable(key, ks, keyT);
 
    encrypt(str, keyT, ps);
}
 
// Driver code
int main()
{
    char str[SIZE], key[SIZE];
 
    // Key to be encrypted
    strcpy(key, "Monarchy");
    printf("Key text: %s\n", key);
 
    // Plaintext to be encrypted
    strcpy(str, "instruments");
    printf("Plain text: %s\n", str);
 
    // encrypt using Playfair Cipher
    encryptByPlayfairCipher(str, key);
 
    printf("Cipher text: %s\n", str);
 
    return 0;
}
 
// This code is contributed by AbhayBhat


Java




// Java program to implement Playfair Cipher
import java.util.*;
 
public class Solution
{
  static int SIZE = 30;
 
  // Function to convert the string to lowercase
  static void toLowerCase(char plain[], int ps)
  {
    int i;
    for (i = 0; i < ps; i++) {
      if (plain[i] > 64 && plain[i] < 91)
        plain[i] += 32;
    }
  }
 
  // Function to remove all spaces in a string
  static int removeSpaces(char[] plain, int ps)
  {
    int i, count = 0;
    for (i = 0; i < ps; i++)
      if (plain[i] != '\u0000')
        plain[count++] = plain[i];
 
    return count;
  }
 
  // Function to generate the 5x5 key square
  static void generateKeyTable(char key[], int ks, char keyT[][])
  {
    int i, j, k, flag = 0;
 
    // a 26 character hashmap
    // to store count of the alphabet
    int dicty[] = new int[26];
    for (i = 0; i < ks; i++) {
      if (key[i] != 'j')
        dicty[key[i] - 97] = 2;
    }
 
    dicty['j' - 97] = 1;
 
    i = 0;
    j = 0;
 
    for (k = 0; k < ks; k++) {
      if (dicty[key[k] - 97] == 2) {
        dicty[key[k] - 97] -= 1;
        keyT[i][j] = key[k];
        j++;
        if (j == 5) {
          i++;
          j = 0;
        }
      }
    }
 
    for (k = 0; k < 26; k++) {
      if (dicty[k] == 0) {
        keyT[i][j] = (char)(k + 97);
        j++;
        if (j == 5) {
          i++;
          j = 0;
        }
      }
    }
  }
 
  // Function to search for the characters of a digraph
  // in the key square and return their position
  static void search(char keyT[][], char a, char b, int arr[])
  {
    int i, j;
 
    if (a == 'j')
      a = 'i';
    else if (b == 'j')
      b = 'i';
 
    for (i = 0; i < 5; i++) {
 
      for (j = 0; j < 5; j++) {
 
        if (keyT[i][j] == a) {
          arr[0] = i;
          arr[1] = j;
        }
        else if (keyT[i][j] == b) {
          arr[2] = i;
          arr[3] = j;
        }
      }
    }
  }
 
  // Function to find the modulus with 5
  static int mod5(int a) { return (a % 5); }
 
  // Function to make the plain text length to be even
  static int prepare(char str[], int ptrs)
  {
    if (ptrs % 2 != 0) {
      str[ptrs++] = 'z';
      str[ptrs] = '\0';
    }
    return ptrs;
  }
 
  // Function for performing the encryption
  static void encrypt(char str[], char keyT[][], int ps)
  {
    int i;
    int[] a =new int[4];
 
    for (i = 0; i < ps; i += 2) {
 
      search(keyT, str[i], str[i + 1], a);
 
      if (a[0] == a[2]) {
        str[i] = keyT[a[0]][mod5(a[1] + 1)];
        str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];
      }
      else if (a[1] == a[3]) {
        str[i] = keyT[mod5(a[0] + 1)][a[1]];
        str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
      }
      else {
        str[i] = keyT[a[0]][a[3]];
        str[i + 1] = keyT[a[2]][a[1]];
      }
    }
  }
 
  // Function to encrypt using Playfair Cipher
  static void encryptByPlayfairCipher(char str[], char key[])
  {
    int ps;
    int ks;
    char[][] keyT = new char[5][5];
 
    // Key
    ks = key.length;
    ks = removeSpaces(key, ks);
    toLowerCase(key, ks);
 
    // Plaintext
    ps = str.length;
    toLowerCase(str, ps);
    ps = removeSpaces(str, ps);
 
    ps = prepare(str, ps);
 
    generateKeyTable(key, ks, keyT);
 
    encrypt(str, keyT, ps);
  }
 
  static void strcpy(char[] arr, String s) {
    for(int i = 0;i < s.length();i++){
      arr[i] = s.charAt(i);
    }
  }
 
  // Driver code
  public static void main(String[] args) {
    char str[] = new char[SIZE];
    char key[] = new char[SIZE];
 
    // Key to be encrypted
 
    strcpy(key, "Monarchy");
    System.out.println("Key text: " + String.valueOf(key));
 
    // Plaintext to be encrypted
    strcpy(str, "instruments");
    System.out.println("Plain text: " + String.valueOf(str));
 
    // encrypt using Playfair Cipher
    encryptByPlayfairCipher(str, key);
 
    System.out.println("Cipher text: " + String.valueOf(str));
  }
 
}
 
// This code is contributed by karandeep1234


Python3




# Python program to implement Playfair Cipher
 
# Function to convert the string to lowercase
 
 
def toLowerCase(text):
    return text.lower()
 
# Function to remove all spaces in a string
 
 
def removeSpaces(text):
    newText = ""
    for i in text:
        if i == " ":
            continue
        else:
            newText = newText + i
    return newText
 
# Function to group 2 elements of a string
# as a list element
 
 
def Diagraph(text):
    Diagraph = []
    group = 0
    for i in range(2, len(text), 2):
        Diagraph.append(text[group:i])
 
        group = i
    Diagraph.append(text[group:])
    return Diagraph
 
# Function to fill a letter in a string element
# If 2 letters in the same string matches
 
 
def FillerLetter(text):
    k = len(text)
    if k % 2 == 0:
        for i in range(0, k, 2):
            if text[i] == text[i+1]:
                new_word = text[0:i+1] + str('x') + text[i+1:]
                new_word = FillerLetter(new_word)
                break
            else:
                new_word = text
    else:
        for i in range(0, k-1, 2):
            if text[i] == text[i+1]:
                new_word = text[0:i+1] + str('x') + text[i+1:]
                new_word = FillerLetter(new_word)
                break
            else:
                new_word = text
    return new_word
 
 
list1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k', 'l', 'm',
         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
 
# Function to generate the 5x5 key square matrix
 
 
def generateKeyTable(word, list1):
    key_letters = []
    for i in word:
        if i not in key_letters:
            key_letters.append(i)
 
    compElements = []
    for i in key_letters:
        if i not in compElements:
            compElements.append(i)
    for i in list1:
        if i not in compElements:
            compElements.append(i)
 
    matrix = []
    while compElements != []:
        matrix.append(compElements[:5])
        compElements = compElements[5:]
 
    return matrix
 
 
def search(mat, element):
    for i in range(5):
        for j in range(5):
            if(mat[i][j] == element):
                return i, j
 
 
def encrypt_RowRule(matr, e1r, e1c, e2r, e2c):
    char1 = ''
    if e1c == 4:
        char1 = matr[e1r][0]
    else:
        char1 = matr[e1r][e1c+1]
 
    char2 = ''
    if e2c == 4:
        char2 = matr[e2r][0]
    else:
        char2 = matr[e2r][e2c+1]
 
    return char1, char2
 
 
def encrypt_ColumnRule(matr, e1r, e1c, e2r, e2c):
    char1 = ''
    if e1r == 4:
        char1 = matr[0][e1c]
    else:
        char1 = matr[e1r+1][e1c]
 
    char2 = ''
    if e2r == 4:
        char2 = matr[0][e2c]
    else:
        char2 = matr[e2r+1][e2c]
 
    return char1, char2
 
 
def encrypt_RectangleRule(matr, e1r, e1c, e2r, e2c):
    char1 = ''
    char1 = matr[e1r][e2c]
 
    char2 = ''
    char2 = matr[e2r][e1c]
 
    return char1, char2
 
 
def encryptByPlayfairCipher(Matrix, plainList):
    CipherText = []
    for i in range(0, len(plainList)):
        c1 = 0
        c2 = 0
        ele1_x, ele1_y = search(Matrix, plainList[i][0])
        ele2_x, ele2_y = search(Matrix, plainList[i][1])
 
        if ele1_x == ele2_x:
            c1, c2 = encrypt_RowRule(Matrix, ele1_x, ele1_y, ele2_x, ele2_y)
            # Get 2 letter cipherText
        elif ele1_y == ele2_y:
            c1, c2 = encrypt_ColumnRule(Matrix, ele1_x, ele1_y, ele2_x, ele2_y)
        else:
            c1, c2 = encrypt_RectangleRule(
                Matrix, ele1_x, ele1_y, ele2_x, ele2_y)
 
        cipher = c1 + c2
        CipherText.append(cipher)
    return CipherText
 
 
text_Plain = 'instruments'
text_Plain = removeSpaces(toLowerCase(text_Plain))
PlainTextList = Diagraph(FillerLetter(text_Plain))
if len(PlainTextList[-1]) != 2:
    PlainTextList[-1] = PlainTextList[-1]+'z'
 
key = "Monarchy"
print("Key text:", key)
key = toLowerCase(key)
Matrix = generateKeyTable(key, list1)
 
print("Plain Text:", text_Plain)
CipherList = encryptByPlayfairCipher(Matrix, PlainTextList)
 
CipherText = ""
for i in CipherList:
    CipherText += i
print("CipherText:", CipherText)
 
# This code is Contributed by Boda_Venkata_Nikith


Javascript




// JavaScript program to implement Playfair Cipher
 
        // Function to generate the 5x5 key square
        function generateKeyTable(key, ks, keyT) {
            let i, j, k, flag = 0;
 
            // a 26 character hashmap
            // to store count of the alphabet
            let dicty = new Array(26).fill(0);
            for (i = 0; i < ks; i++) {
                let r = key[i].charCodeAt(0) - 97;
 
                if (key[i] != 'j') {
                    dicty[r] = 2;
                }
 
            }
 
            dicty['j'.charCodeAt(0) - 97] = 1;
            i = 0;
            j = 0;
 
            for (k = 0; k < ks; k++) {
                let r = key[k].charCodeAt(0) - 97;
                if (dicty[r] == 2) {
                    dicty[r] -= 1;
                    keyT[i][j] = key[k];
                    j++;
                    if (j == 5) {
                        i++;
                        j = 0;
                    }
                }
            }
 
            for (k = 0; k < 26; k++) {
                if (dicty[k] == 0) {
                    keyT[i][j] = String.fromCharCode(k + 97);
                    j++;
                    if (j == 5) {
                        i++;
                        j = 0;
                    }
                }
            }
            return keyT;
        }
 
        // Function to search for the characters of a digraph
        // in the key square and return their position
        function search(keyT, a, b, arr) {
            let i, j;
 
            if (a == 'j')
                a = 'i';
            else if (b == 'j')
                b = 'i';
 
            for (i = 0; i < 5; i++) {
 
                for (j = 0; j < 5; j++) {
 
                    if (keyT[i][j] == a) {
                        arr[0] = i;
                        arr[1] = j;
                    }
                    else if (keyT[i][j] == b) {
                        arr[2] = i;
                        arr[3] = j;
                    }
                }
            }
            return arr;
        }
 
        // Function to find the modulus with 5
        function mod5(a) {
            return (a % 5);
        }
 
        // Function to make the plain text length to be even
        function prepare(str, ptrs) {
            if (ptrs % 2 != 0) {
                str += 'z';
            }
 
            return [str, ptrs];
        }
 
        // Function for performing the encryption
        function encrypt(str, keyT, ps) {
            let i;
            let a = new Array(4).fill(0);
            let newstr = new Array(ps);
 
            for (i = 0; i < ps; i += 2) {
                let brr = search(keyT, str[i], str[i + 1], a);
                let k1 = brr[0];
                let k2 = brr[1];
                let k3 = brr[2];
                let k4 = brr[3];
                if (k1 == k3) {
                    newstr[i] = keyT[k1][(k2 + 1) % 5];
                    newstr[i + 1] = keyT[k1][(k4 + 1) % 5];
                }
                else if (k2 == k4) {
                    newstr[i] = keyT[(k1 + 1) % 5][k2];
                    newstr[i + 1] = keyT[(k3 + 1) % 5][k2];
                }
                else {
                    newstr[i] = keyT[k1][k4];
                    newstr[i + 1] = keyT[k3][k2];
                }
            }
            let res = "";
 
            for (let i = 0; i < newstr.length; i++) { res += newstr[i]; }
            return res;
        }
 
        // Function to encrypt using Playfair Cipher
        function encryptByPlayfairCipher(str, key) {
            let ps, ks;
            let keyT = new Array(5);
 
            for (let i = 0; i < 5; i++) {
                keyT[i] = new Array(5);
            }
            str = str.trim();
            key = key.trim();
            str = str.toLowerCase();
 
            key = key.toLowerCase();
            ps = str.length;
            ks = key.length;
            [str, ps] = prepare(str, ps);
 
            let kt = generateKeyTable(key, ks, keyT);
            return encrypt(str, kt, ps);
        }
 
        // Driver code
        let key = " Monarchy";
        let str = " instruments";
 
        // Key to be encrypted
 
        console.log("Key text: " + key + "<br>");
 
        console.log("Plain text: " + str + "<br>");
        // encrypt using Playfair Cipher
 
        console.log("Cipher text: " + encryptByPlayfairCipher(str, key));
         
        // This code is contributed by poojaagarwal2


Output

Key text: Monarchy
Plain text: instruments
Cipher text: gatlmzclrqtx
Decryption Technique

Decrypting the Playfair cipher is as simple as doing the same process in reverse. The receiver has the same key and can create the same key table, and then decrypt any messages made using that key.
 

Decryption Technique

The Playfair Cipher Decryption Algorithm: 
The Algorithm consists of 2 steps: 
 

  1. Generate the key Square(5×5) at the receiver’s end: 
    • The key square is a 5×5 grid of alphabets that acts as the key for encrypting the plaintext. Each of the 25 alphabets must be unique and one letter of the alphabet (usually J) is omitted from the table (as the table can hold only 25 alphabets). If the plaintext contains J, then it is replaced by I. 
       
    • The initial alphabets in the key square are the unique alphabets of the key in the order in which they appear followed by the remaining letters of the alphabet in order. 
       
  2. Algorithm to decrypt the ciphertext: The ciphertext is split into pairs of two letters (digraphs). 
     

Note: The ciphertext always have even number of characters.

  1. For example: 
     
CipherText: "gatlmzclrqtx" 
After Split: 'ga' 'tl' 'mz' 'cl' 'rq' 'tx'
  1. Rules for Decryption: 
    • If both the letters are in the same column: Take the letter above each one (going back to the bottom if at the top).
      For example: 
       
Diagraph: "cl" 
Decrypted Text: me
Decryption:
c -> m
l -> e
  •  

algorithm to decrypt the ciphertext

  •  
  • If both the letters are in the same row: Take the letter to the left of each one (going back to the rightmost if at the leftmost position).
    For example: 
     
Diagraph: "tl" 
Decrypted Text: st
Decryption:
t -> s
l -> t
  •  

Rules for Decryption 1

  •  
  • If neither of the above rules is true: Form a rectangle with the two letters and take the letters on the horizontal opposite corner of the rectangle.
    For example: 
     
Diagraph: "rq" 
Decrypted Text: nt
Decryption:
r -> n
q -> t
  •  

Rules for Decryption 2

  •  

For example: 
 

Plain Text: "gatlmzclrqtx"
Decrypted Text: instrumentsz
Decryption:
(red)-> (green)
ga -> in
tl -> st
mz -> ru
cl -> me
rq -> nt
tx -> sz

 

Example of Decryption

Below is an implementation of Playfair Cipher Decryption in C: 
 

C++




#include <bits/stdc++.h>
using namespace std;
#define SIZE 30
 
// Convert all the characters
// of a string to lowercase
void toLowerCase(char plain[], int ps)
{
    int i;
    for (i = 0; i < ps; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}
 
// Remove all spaces in a string
// can be extended to remove punctuation
int removeSpaces(char* plain, int ps)
{
    int i, count = 0;
    for (i = 0; i < ps; i++)
        if (plain[i] != ' ')
            plain[count++] = plain[i];
    plain[count] = '\0';
    return count;
}
 
// generates the 5x5 key square
void generateKeyTable(char key[], int ks, char keyT[5][5])
{
    int i, j, k, flag = 0, *dicty;
 
    // a 26 character hashmap
    // to store count of the alphabet
    dicty = (int*)calloc(26, sizeof(int));
 
    for (i = 0; i < ks; i++) {
        if (key[i] != 'j')
            dicty[key[i] - 97] = 2;
    }
    dicty['j' - 97] = 1;
 
    i = 0;
    j = 0;
    for (k = 0; k < ks; k++) {
        if (dicty[key[k] - 97] == 2) {
            dicty[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
    for (k = 0; k < 26; k++) {
        if (dicty[k] == 0) {
            keyT[i][j] = (char)(k + 97);
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
}
 
// Search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
    int i, j;
 
    if (a == 'j')
        a = 'i';
    else if (b == 'j')
        b = 'i';
 
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 5; j++) {
            if (keyT[i][j] == a) {
                arr[0] = i;
                arr[1] = j;
            }
            else if (keyT[i][j] == b) {
                arr[2] = i;
                arr[3] = j;
            }
        }
    }
}
 
// Function to find the modulus with 5
int mod5(int a)
{
    if (a < 0)
        a += 5;
    return (a % 5);
}
 
// Function to decrypt
void decrypt(char str[], char keyT[5][5], int ps)
{
    int i, a[4];
    for (i = 0; i < ps; i += 2) {
        search(keyT, str[i], str[i + 1], a);
        if (a[0] == a[2]) {
            str[i] = keyT[a[0]][mod5(a[1] - 1)];
            str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
        }
        else if (a[1] == a[3]) {
            str[i] = keyT[mod5(a[0] - 1)][a[1]];
            str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
        }
        else {
            str[i] = keyT[a[0]][a[3]];
            str[i + 1] = keyT[a[2]][a[1]];
        }
    }
}
 
// Function to call decrypt
void decryptByPlayfairCipher(char str[], char key[])
{
    char ps, ks, keyT[5][5];
 
    // Key
    ks = strlen(key);
    ks = removeSpaces(key, ks);
    toLowerCase(key, ks);
 
    // ciphertext
    ps = strlen(str);
    toLowerCase(str, ps);
    ps = removeSpaces(str, ps);
 
    generateKeyTable(key, ks, keyT);
 
    decrypt(str, keyT, ps);
}
 
// Driver code
int main()
{
    char str[SIZE], key[SIZE];
 
    // Key to be encrypted
    strcpy(key, "Monarchy");
    cout << "Key Text: " << key << endl;
 
    // Ciphertext to be decrypted
    strcpy(str, "gatlmzclrqtx");
    cout << "Plain text: " << str << endl;
 
    // encrypt using Playfair Cipher
    decryptByPlayfairCipher(str, key);
 
    cout << "Deciphered text: " << str << endl;
 
    return 0;
}
 
// This code is contributed by YASH
// AGARWAL(YASHAGARWAL2852002)


C




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
 
// Convert all the characters
// of a string to lowercase
void toLowerCase(char plain[], int ps)
{
    int i;
    for (i = 0; i < ps; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}
 
// Remove all spaces in a string
// can be extended to remove punctuation
int removeSpaces(char* plain, int ps)
{
    int i, count = 0;
    for (i = 0; i < ps; i++)
        if (plain[i] != ' ')
            plain[count++] = plain[i];
    plain[count] = '\0';
    return count;
}
 
// generates the 5x5 key square
void generateKeyTable(char key[], int ks, char keyT[5][5])
{
    int i, j, k, flag = 0, *dicty;
 
    // a 26 character hashmap
    // to store count of the alphabet
    dicty = (int*)calloc(26, sizeof(int));
 
    for (i = 0; i < ks; i++) {
        if (key[i] != 'j')
            dicty[key[i] - 97] = 2;
    }
    dicty['j' - 97] = 1;
 
    i = 0;
    j = 0;
    for (k = 0; k < ks; k++) {
        if (dicty[key[k] - 97] == 2) {
            dicty[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
    for (k = 0; k < 26; k++) {
        if (dicty[k] == 0) {
            keyT[i][j] = (char)(k + 97);
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }
}
 
// Search for the characters of a digraph
// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[])
{
    int i, j;
 
    if (a == 'j')
        a = 'i';
    else if (b == 'j')
        b = 'i';
 
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 5; j++) {
            if (keyT[i][j] == a) {
                arr[0] = i;
                arr[1] = j;
            }
            else if (keyT[i][j] == b) {
                arr[2] = i;
                arr[3] = j;
            }
        }
    }
}
 
// Function to find the modulus with 5
int mod5(int a)
{
    if (a < 0)
        a += 5;
    return (a % 5);
}
 
// Function to decrypt
void decrypt(char str[], char keyT[5][5], int ps)
{
    int i, a[4];
    for (i = 0; i < ps; i += 2) {
        search(keyT, str[i], str[i + 1], a);
        if (a[0] == a[2]) {
            str[i] = keyT[a[0]][mod5(a[1] - 1)];
            str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
        }
        else if (a[1] == a[3]) {
            str[i] = keyT[mod5(a[0] - 1)][a[1]];
            str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
        }
        else {
            str[i] = keyT[a[0]][a[3]];
            str[i + 1] = keyT[a[2]][a[1]];
        }
    }
}
 
// Function to call decrypt
void decryptByPlayfairCipher(char str[], char key[])
{
    char ps, ks, keyT[5][5];
 
    // Key
    ks = strlen(key);
    ks = removeSpaces(key, ks);
    toLowerCase(key, ks);
 
    // ciphertext
    ps = strlen(str);
    toLowerCase(str, ps);
    ps = removeSpaces(str, ps);
 
    generateKeyTable(key, ks, keyT);
 
    decrypt(str, keyT, ps);
}
 
// Driver code
int main()
{
    char str[SIZE], key[SIZE];
 
    // Key to be encrypted
    strcpy(key, "Monarchy");
    printf("Key text: %s\n", key);
 
    // Ciphertext to be decrypted
    strcpy(str, "gatlmzclrqtx");
    printf("Plain text: %s\n", str);
 
    // encrypt using Playfair Cipher
    decryptByPlayfairCipher(str, key);
 
    printf("Deciphered text: %s\n", str);
 
    return 0;
}
 
// This code is contributed by AbhayBhat


Java




import java.util.Arrays;
 
public class PlayfairCipher {
    // Function to convert all characters of a string to lowercase
    static String toLowerCase(String plain) {
        return plain.toLowerCase();
    }
 
    // Function to remove all spaces in a string
    // Can be extended to remove punctuation
    static String removeSpaces(String plain) {
        return plain.replaceAll(" ", "");
    }
 
    // Function to generate the 5x5 key square
    static char[][] generateKeyTable(String key) {
        char[][] keyT = new char[5][5];
        int[] dicty = new int[26];
 
        // Initialize the hashmap to store the count of each alphabet
        Arrays.fill(dicty, 0);
 
        for (int i = 0; i < key.length(); i++) {
            if (key.charAt(i) != 'j')
                dicty[key.charAt(i) - 97] = 2;
        }
        dicty['j' - 97] = 1;
 
        int i = 0, j = 0;
        for (int k = 0; k < key.length(); k++) {
            if (dicty[key.charAt(k) - 97] == 2) {
                dicty[key.charAt(k) - 97] -= 1;
                keyT[i][j] = key.charAt(k);
                j++;
                if (j == 5) {
                    i++;
                    j = 0;
                }
            }
        }
 
        for (int k = 0; k < 26; k++) {
            if (dicty[k] == 0) {
                keyT[i][j] = (char) (k + 97);
                j++;
                if (j == 5) {
                    i++;
                    j = 0;
                }
            }
        }
        return keyT;
    }
 
    // Function to search for the characters of a digraph in the key square and return their position
    static void search(char[][] keyT, char a, char b, int[] arr) {
        if (a == 'j')
            a = 'i';
        else if (b == 'j')
            b = 'i';
 
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (keyT[i][j] == a) {
                    arr[0] = i;
                    arr[1] = j;
                } else if (keyT[i][j] == b) {
                    arr[2] = i;
                    arr[3] = j;
                }
            }
        }
    }
 
    // Function to decrypt
    static void decrypt(char[] str, char[][] keyT) {
        for (int i = 0; i < str.length; i += 2) {
            int[] a = new int[4];
            search(keyT, str[i], str[i + 1], a);
            if (a[0] == a[2]) {
                str[i] = keyT[a[0]][mod5(a[1] - 1)];
                str[i + 1] = keyT[a[0]][mod5(a[3] - 1)];
            } else if (a[1] == a[3]) {
                str[i] = keyT[mod5(a[0] - 1)][a[1]];
                str[i + 1] = keyT[mod5(a[2] - 1)][a[1]];
            } else {
                str[i] = keyT[a[0]][a[3]];
                str[i + 1] = keyT[a[2]][a[1]];
            }
        }
    }
 
    // Function to calculate the modulus with 5
    static int mod5(int a) {
        if (a < 0)
            a += 5;
        return (a % 5);
    }
 
    // Function to call decrypt
    static void decryptByPlayfairCipher(char[] str, String key) {
        // Key
        key = removeSpaces(toLowerCase(key));
 
        // Key Table
        char[][] keyT = generateKeyTable(key);
 
        // Decrypt
        decrypt(str, keyT);
    }
 
    // Driver code
    public static void main(String[] args) {
        // Key to be decrypted
        String key = "Monarchy";
        System.out.println("Key Text: " + key);
 
        // Ciphertext to be decrypted
        char[] str = "gatlmzclrqtx".toCharArray();
        System.out.println("Ciphertext: " + String.valueOf(str));
 
        // Decrypt using Playfair Cipher
        decryptByPlayfairCipher(str, key);
 
        // Deciphered text
        System.out.println("Deciphered text: " + String.valueOf(str));
    }
}


Python3




def toLowerCase(plain):
    # Convert all the characters of a string to lowercase
    return plain.lower()
 
 
def removeSpaces(plain):
    # Remove all spaces in a string
    # can be extended to remove punctuation
    return ''.join(plain.split())
 
 
def generateKeyTable(key):
    # generates the 5x5 key square
    keyT = [['' for i in range(5)] for j in range(5)]
    dicty = {chr(i + 97): 0 for i in range(26)}
 
    for i in range(len(key)):
        if key[i] != 'j':
            dicty[key[i]] = 2
    dicty['j'] = 1
 
    i, j, k = 0, 0, 0
    while k < len(key):
        if dicty[key[k]] == 2:
            dicty[key[k]] -= 1
            keyT[i][j] = key[k]
            j += 1
            if j == 5:
                i += 1
                j = 0
        k += 1
 
    for k in dicty.keys():
        if dicty[k] == 0:
            keyT[i][j] = k
            j += 1
            if j == 5:
                i += 1
                j = 0
 
    return keyT
 
 
def search(keyT, a, b):
    # Search for the characters of a digraph in the key square and return their position
    arr = [0, 0, 0, 0]
 
    if a == 'j':
        a = 'i'
    elif b == 'j':
        b = 'i'
 
    for i in range(5):
        for j in range(5):
            if keyT[i][j] == a:
                arr[0], arr[1] = i, j
            elif keyT[i][j] == b:
                arr[2], arr[3] = i, j
 
    return arr
 
 
def mod5(a):
    # Function to find the modulus with 5
    if a < 0:
        a += 5
    return a % 5
 
 
def decrypt(str, keyT):
    # Function to decrypt
    ps = len(str)
    i = 0
    while i < ps:
        a = search(keyT, str[i], str[i+1])
        if a[0] == a[2]:
            str = str[:i] + keyT[a[0]
                                 ][mod5(a[1]-1)] + keyT[a[0]][mod5(a[3]-1)] + str[i+2:]
        elif a[1] == a[3]:
            str = str[:i] + keyT[mod5(a[0]-1)][a[1]] + \
                keyT[mod5(a[2]-1)][a[1]] + str[i+2:]
        else:
            str = str[:i] + keyT[a[0]][a[3]] + keyT[a[2]][a[1]] + str[i+2:]
        i += 2
 
    return str
 
 
def decryptByPlayfairCipher(str, key):
    # Function to call decrypt
    ks = len(key)
    key = removeSpaces(toLowerCase(key))
    str = removeSpaces(toLowerCase(str))
    keyT = generateKeyTable(key)
    return decrypt(str, keyT)
 
 
if __name__ == '__main__':
    str = "gatlmzclrqtx"
    key = "Monarchy"
 
    # Key to be encrypted
    print("Key text: ", key)
 
    # Ciphertext to be decrypted
    print("Plain text: ", str)
 
    # encrypt using Playfair Cipher
    decryptByPlayfairCipher(str, key)
 
    # Decrypted text
    print("Deciphered text: ", str)
 
 # Pyhton Code Written By Kushal Prajapati


Javascript




function toLowerCase(plain) {
  // Convert all the characters of a string to lowercase
  return plain.toLowerCase();
}
 
function removeSpaces(plain) {
  // Remove all spaces in a string
  // can be extended to remove punctuation
  return plain.split(' ').join('');
}
 
function generateKeyTable(key) {
  // generates the 5x5 key square
  var keyT = new Array(5).fill(null).map(() => new Array(5).fill(''));
  var dicty = {};
  for (var i = 0; i < 26; i++) {
    dicty[String.fromCharCode(i + 97)] = 0;
  }
 
  for (var i = 0; i < key.length; i++) {
    if (key[i] != 'j') {
      dicty[key[i]] = 2;
    }
  }
  dicty['j'] = 1;
 
  var i = 0, j = 0, k = 0;
  while (k < key.length) {
    if (dicty[key[k]] == 2) {
      dicty[key[k]] -= 1;
      keyT[i][j] = key[k];
      j += 1;
      if (j == 5) {
        i += 1;
        j = 0;
      }
    }
    k += 1;
  }
 
  for (var k in dicty) {
    if (dicty[k] == 0) {
      keyT[i][j] = k;
      j += 1;
      if (j == 5) {
        i += 1;
        j = 0;
      }
    }
  }
 
  return keyT;
}
 
function search(keyT, a, b) {
  // Search for the characters of a digraph in the key square and return their position
  var arr = [0, 0, 0, 0];
 
  if (a == 'j') {
    a = 'i';
  } else if (b == 'j') {
    b = 'i';
  }
 
  for (var i = 0; i < 5; i++) {
    for (var j = 0; j < 5; j++) {
      if (keyT[i][j] == a) {
        arr[0] = i;
        arr[1] = j;
      } else if (keyT[i][j] == b) {
        arr[2] = i;
        arr[3] = j;
      }
    }
  }
 
  return arr;
}
 
function mod5(a) {
  // Function to find the modulus with 5
  if (a < 0) {
    a += 5;
  }
  return a % 5;
}
function decrypt(str, keyT) {
// Function to decrypt
var ps = str.length;
var i = 0;
while (i < ps) {
var a = search(keyT, str[i], str[i + 1]);
if (a[0] == a[2]) {
str = str.slice(0, i) + keyT[a[0]][mod5(a[1] - 1)] + keyT[a[0]][mod5(a[3] - 1)] + str.slice(i + 2);
} else if (a[1] == a[3]) {
str = str.slice(0, i) + keyT[mod5(a[0] - 1)][a[1]] + keyT[mod5(a[2] - 1)][a[1]] + str.slice(i + 2);
} else {
str = str.slice(0, i) + keyT[a[0]][a[3]] + keyT[a[2]][a[1]] + str.slice(i + 2);
}
i += 2;
}
return str;
}
 
function decryptByPlayfairCipher(str, key) {
// Function to call decrypt
var ks = key.length;
key = removeSpaces(toLowerCase(key));
str = removeSpaces(toLowerCase(str));
var keyT = generateKeyTable(key);
return decrypt(str, keyT);
}
 
// Example usage
var str = "gatlmzclrqtx";
var key = "Monarchy";
 
// Key to be decrypted
console.log("Key text:", key);
 
// Ciphertext to be decrypted
console.log("Plain text:", str);
 
// decrypt using Playfair Cipher
var plainText = decryptByPlayfairCipher(str, key);
 
// Decrypted text
console.log("Deciphered text:", plainText);


Output

Key text: Monarchy
Plain text: gatlmzclrqtx
Deciphered text: instrumentsz
Advantages and Disadvantages
  • Advantages: 
    1. It is significantly harder to break since the frequency analysis technique used to break simple substitution ciphers is difficult but still can be used on (25*25) = 625 digraphs rather than 25 monographs which is difficult. 
       
    2. Frequency analysis thus requires more cipher text to crack the encryption. 
       
  • Disadvantages: 
    1. An interesting weakness is the fact that a digraph in the ciphertext (AB) and it’s reverse (BA) will have corresponding plaintexts like UR and RU (and also ciphertext UR and RU will correspond to plaintext AB and BA, i.e. the substitution is self-inverse). That can easily be exploited with the aid of frequency analysis, if the language of the plaintext is known. 
       
    2. Another disadvantage is that playfair cipher is a symmetric cipher thus same key is used for both encryption and decryption. 
       


Last Updated : 06 Mar, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads