Playfair Cipher with Examples

Last Updated : 12 Jul, 2025

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

The algorithm consists of 2 steps: 

  1. Generate the key Square (5x5): 
    • 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.  

Example:

PlainText: "instruments"
After Split: 'in' 'st' 'ru' 'me' 'nt' 'sz'
Explanation: Pair cannot be made with same letter. Break the letter in single and add a bogus letter to the previous letter. Here 'z' is the bogus letter.

Plain Text: "hello"
After Split: 'he' 'lx' 'lo'
Explanation: Here 'x' is the bogus letter.

Plain Text: "helloe"
After Split: 'he' 'lx' 'lo' 'ez'
Explanation: If the letter is standing alone in the process of pairing, then add an extra bogus letter with the alone letter. Here 'x' and 'z'  are the bogus letters.

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 given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// Function to convert the string to lowercase
void toLowerCase(string &plain) {
    int n = plain.size();
    for (int i = 0; i < n; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}

// Function to remove all spaces in a string
void removeSpaces(string &plain) {
    int n = plain.size();
    string temp;
    for (int i = 0; i < n; i++) {
        if (plain[i] != ' ') {
            temp += plain[i];
        }
    }
    plain = temp;
}

// Function to generate the 5x5 key square
void generateKeyTable(string &key, 
        vector<vector<char>> &keyT) {
    int n = key.size();

    // 5x5 key table
    keyT.resize(5, vector<char>(5, 0));

    // a 26 character hashmap
    // to store count of the alphabet
    vector<int> hash(26, 0);

    int i, j, k, flag = 0;
    for (i = 0; i < n; i++) {
        if (key[i] != 'j')
            hash[key[i] - 97] = 2;
    }

    hash['j' - 97] = 1;

    i = 0;
    j = 0;

    for (k = 0; k < n; k++) {
        if (hash[key[k] - 97] == 2) {
            hash[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }

    for (k = 0; k < 26; k++) {
        if (hash[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(vector<vector<char>> &keyT, 
        char a, char b, vector<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 make the plain text length to be even
int prepare(string &str) {
    if (str.size() % 2 != 0) {
        str += 'z';
    }
    int n = str.size();
    return n;
}

// Function for performing the encryption
void encrypt(string &str, vector<vector<char>> &keyT) {
    int n = str.size();
    vector<int> arr(4);

    for (int i = 0; i < n; i += 2) {

        search(keyT, str[i], str[i + 1], arr);

        if (arr[0] == arr[2]) {
            str[i] = keyT[arr[0]][(arr[1] + 1) % 5];
            str[i + 1] = keyT[arr[0]][(arr[3] + 1) % 5];
        }
        else if (arr[1] == arr[3]) {
            str[i] = keyT[(arr[0] + 1) % 5][arr[1]];
            str[i + 1] = keyT[(arr[2] + 1) % 5][arr[1]];
        }
        else {
            str[i] = keyT[arr[0]][arr[3]];
            str[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
}

// Function to encrypt using Playfair Cipher
void encryptByPlayfairCipher(string &str, string &key) {
    vector<vector<char>> keyT;
    removeSpaces(key);
    toLowerCase(key);
    toLowerCase(str);
    removeSpaces(str);
    prepare(str);
    generateKeyTable(key, keyT);
    encrypt(str, keyT);
}

int main() {
    string key = "Monarchy";
    string str = "instruments";
    cout << "Key text: " << key << endl;
    cout << "Plain text: " << str << endl;
    encryptByPlayfairCipher(str, key);
    cout << "Cipher text: " << str << endl;
    return 0;
}
C
#include <stdio.h>
#include <string.h>
#include <ctype.h>

// Function to convert the string to lowercase
void toLowerCase(char *plain) {
    int n = strlen(plain);
    for (int i = 0; i < n; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}

// Function to remove all spaces in a string
void removeSpaces(char *plain) {
    int n = strlen(plain);
    char temp[100];
    int k = 0;
    for (int i = 0; i < n; i++) {
        if (plain[i] != ' ') {
            temp[k++] = plain[i];
        }
    }
    temp[k] = '\0';
    strcpy(plain, temp);
}

// Function to generate the 5x5 key square
void generateKeyTable(char *key, char keyT[5][5]) {
    int n = strlen(key);

    int hash[26] = {0};

    for (int i = 0; i < n; i++) {
        if (key[i] != 'j')
            hash[key[i] - 97] = 2;
    }

    hash['j' - 97] = 1;

    int i = 0, j = 0;

    for (int k = 0; k < n; k++) {
        if (hash[key[k] - 97] == 2) {
            hash[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }

    for (int k = 0; k < 26; k++) {
        if (hash[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[4]) {
    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 make the plain text length to be even
int prepare(char *str) {
    int n = strlen(str);
    if (n % 2 != 0) {
        str[n] = 'z';
        str[n + 1] = '\0';
    }
    return strlen(str);
}

// Function for performing the encryption
void encrypt(char *str, char keyT[5][5]) {
    int n = strlen(str);
    int arr[4];

    for (int i = 0; i < n; i += 2) {
        search(keyT, str[i], str[i + 1], arr);

        if (arr[0] == arr[2]) {
            str[i] = keyT[arr[0]][(arr[1] + 1) % 5];
            str[i + 1] = keyT[arr[0]][(arr[3] + 1) % 5];
        }
        else if (arr[1] == arr[3]) {
            str[i] = keyT[(arr[0] + 1) % 5][arr[1]];
            str[i + 1] = keyT[(arr[2] + 1) % 5][arr[1]];
        }
        else {
            str[i] = keyT[arr[0]][arr[3]];
            str[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
}

// Function to encrypt using Playfair Cipher
void encryptByPlayfairCipher(char *str, char *key) {
    char keyT[5][5];
    removeSpaces(key);
    toLowerCase(key);
    toLowerCase(str);
    removeSpaces(str);
    prepare(str);
    generateKeyTable(key, keyT);
    encrypt(str, keyT);
}

int main() {
    char key[100] = "Monarchy";
    char str[100] = "instruments";
    printf("Key text: %s\n", key);
    printf("Plain text: %s\n", str);
    encryptByPlayfairCipher(str, key);
    printf("Cipher text: %s\n", str);
    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to convert the string to lowercase
    static void toLowerCase(StringBuilder plain) {
        for (int i = 0; i < plain.length(); i++) {
            if (plain.charAt(i) > 64 && plain.charAt(i) < 91)
                plain.setCharAt(i, (char)(plain.charAt(i) + 32));
        }
    }

    // Function to remove all spaces in a string
    static void removeSpaces(StringBuilder plain) {
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < plain.length(); i++) {
            if (plain.charAt(i) != ' ') {
                temp.append(plain.charAt(i));
            }
        }
        plain.setLength(0);
        plain.append(temp);
    }

    // Function to generate the 5x5 key square
    static void generateKeyTable(StringBuilder key, char[][] keyT) {
        int n = key.length();

        int[] hash = new int[26];

        for (int i = 0; i < n; i++) {
            if (key.charAt(i) != 'j')
                hash[key.charAt(i) - 97] = 2;
        }

        hash['j' - 97] = 1;

        int i = 0, j = 0;

        for (int k = 0; k < n; k++) {
            if (hash[key.charAt(k) - 97] == 2) {
                hash[key.charAt(k) - 97] -= 1;
                keyT[i][j++] = key.charAt(k);
                if (j == 5) {
                    i++;
                    j = 0;
                }
            }
        }

        for (int k = 0; k < 26; k++) {
            if (hash[k] == 0) {
                keyT[i][j++] = (char)(k + 97);
                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) {
        if (a == 'j') a = 'i';
        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 make the plain text length to be even
    static int prepare(StringBuilder str) {
        if (str.length() % 2 != 0) {
            str.append('z');
        }
        return str.length();
    }

    // Function for performing the encryption
    static void encrypt(StringBuilder str, char[][] keyT) {
        int[] arr = new int[4];
        for (int i = 0; i < str.length(); i += 2) {
            search(keyT, str.charAt(i), str.charAt(i + 1), arr);

            if (arr[0] == arr[2]) {
                str.setCharAt(i, keyT[arr[0]][(arr[1] + 1) % 5]);
                str.setCharAt(i + 1, keyT[arr[0]][(arr[3] + 1) % 5]);
            } else if (arr[1] == arr[3]) {
                str.setCharAt(i, keyT[(arr[0] + 1) % 5][arr[1]]);
                str.setCharAt(i + 1, keyT[(arr[2] + 1) % 5][arr[1]]);
            } else {
                str.setCharAt(i, keyT[arr[0]][arr[3]]);
                str.setCharAt(i + 1, keyT[arr[2]][arr[1]]);
            }
        }
    }

    // Function to encrypt using Playfair Cipher
    static void encryptByPlayfairCipher(
        StringBuilder str, StringBuilder key) {
        char[][] keyT = new char[5][5];
        removeSpaces(key);
        toLowerCase(key);
        toLowerCase(str);
        removeSpaces(str);
        prepare(str);
        generateKeyTable(key, keyT);
        encrypt(str, keyT);
    }

    public static void main(String[] args) {
        StringBuilder key = new StringBuilder("Monarchy");
        StringBuilder str = new StringBuilder("instruments");
        System.out.println("Key text: " + key);
        System.out.println("Plain text: " + str);
        encryptByPlayfairCipher(str, key);
        System.out.println("Cipher text: " + str);
    }
}
Python
# Function to convert the string to lowercase
def toLowerCase(plain):
    n = len(plain)
    result = ""
    for i in range(n):
        if 64 < ord(plain[i]) < 91:
            result += chr(ord(plain[i]) + 32)
        else:
            result += plain[i]
    return result

# Function to remove all spaces in a string
def removeSpaces(plain):
    n = len(plain)
    temp = ""
    for i in range(n):
        if plain[i] != ' ':
            temp += plain[i]
    return temp

# Function to generate the 5x5 key square
def generateKeyTable(key, keyT):
    n = len(key)

    keyT.clear()
    for i in range(5):
        keyT.append([0]*5)

    hashMap = [0]*26

    for i in range(n):
        if key[i] != 'j':
            hashMap[ord(key[i]) - 97] = 2

    hashMap[ord('j') - 97] = 1

    i = 0
    j = 0

    for k in range(n):
        if hashMap[ord(key[k]) - 97] == 2:
            hashMap[ord(key[k]) - 97] -= 1
            keyT[i][j] = key[k]
            j += 1
            if j == 5:
                i += 1
                j = 0

    for k in range(26):
        if hashMap[k] == 0:
            keyT[i][j] = chr(k + 97)
            j += 1
            if j == 5:
                i += 1
                j = 0

# Function to search for the characters of a digraph
# in the key square and return their position
def search(keyT, a, b, arr):
    if a == 'j':
        a = 'i'
    if b == 'j':
        b = 'i'

    for i in range(5):
        for j in range(5):
            if keyT[i][j] == a:
                arr[0] = i
                arr[1] = j
            elif keyT[i][j] == b:
                arr[2] = i
                arr[3] = j

# Function to make the plain text length to be even
def prepare(string):
    if len(string) % 2 != 0:
        string += 'z'
    return string

# Function for performing the encryption
def encrypt(string, keyT):
    n = len(string)
    arr = [0]*4

    result = list(string)
    for i in range(0, n, 2):
        search(keyT, result[i], result[i+1], arr)

        if arr[0] == arr[2]:
            result[i] = keyT[arr[0]][(arr[1] + 1) % 5]
            result[i+1] = keyT[arr[0]][(arr[3] + 1) % 5]
        elif arr[1] == arr[3]:
            result[i] = keyT[(arr[0] + 1) % 5][arr[1]]
            result[i+1] = keyT[(arr[2] + 1) % 5][arr[1]]
        else:
            result[i] = keyT[arr[0]][arr[3]]
            result[i+1] = keyT[arr[2]][arr[1]]

    return ''.join(result)

# Function to encrypt using Playfair Cipher
def encryptByPlayfairCipher(string, key):
    keyT = []
    key = toLowerCase(removeSpaces(key))
    string = toLowerCase(removeSpaces(string))
    string = prepare(string)
    generateKeyTable(key, keyT)
    return encrypt(string, keyT)

key = "Monarchy"
string = "instruments"
print("Key text:", key)
print("Plain text:", string)
string = encryptByPlayfairCipher(string, key)
print("Cipher text:", string)
C#
using System;
using System.Collections.Generic;

public class GfG {

    // Function to convert the string to lowercase
    static void toLowerCase(ref string plain) {
        char[] arr = plain.ToCharArray();
        for (int i = 0; i < arr.Length; i++) {
            if (arr[i] > 64 && arr[i] < 91)
                arr[i] = (char)(arr[i] + 32);
        }
        plain = new string(arr);
    }

    // Function to remove all spaces in a string
    static void removeSpaces(ref string plain) {
        string temp = "";
        for (int i = 0; i < plain.Length; i++) {
            if (plain[i] != ' ')
                temp += plain[i];
        }
        plain = temp;
    }

    // Function to generate the 5x5 key square
    static void generateKeyTable(ref string key, char[,] keyT) {
        int n = key.Length;
        int[] hash = new int[26];

        for (int i = 0; i < n; i++) {
            if (key[i] != 'j')
                hash[key[i] - 'a'] = 2;
        }

        hash['j' - 'a'] = 1;

        int row = 0, col = 0;

        for (int k = 0; k < n; k++) {
            if (hash[key[k] - 'a'] == 2) {
                hash[key[k] - 'a'] -= 1;
                keyT[row, col++] = key[k];
                if (col == 5) {
                    row++;
                    col = 0;
                }
            }
        }

        for (int k = 0; k < 26; k++) {
            if (hash[k] == 0) {
                keyT[row, col++] = (char)(k + 'a');
                if (col == 5) {
                    row++;
                    col = 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) {
        if (a == 'j') a = 'i';
        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 make the plain text length to be even
    static int prepare(ref string str) {
        if (str.Length % 2 != 0)
            str += 'z';
        return str.Length;
    }

    // Function for performing the encryption
    static void encrypt(ref string str, char[,] keyT) {
        int n = str.Length;
        int[] arr = new int[4];
        char[] ch = str.ToCharArray();

        for (int i = 0; i < n; i += 2) {
            search(keyT, ch[i], ch[i + 1], arr);

            if (arr[0] == arr[2]) {
                ch[i] = keyT[arr[0], (arr[1] + 1) % 5];
                ch[i + 1] = keyT[arr[0], (arr[3] + 1) % 5];
            } else if (arr[1] == arr[3]) {
                ch[i] = keyT[(arr[0] + 1) % 5, arr[1]];
                ch[i + 1] = keyT[(arr[2] + 1) % 5, arr[1]];
            } else {
                ch[i] = keyT[arr[0], arr[3]];
                ch[i + 1] = keyT[arr[2], arr[1]];
            }
        }
        str = new string(ch);
    }

    // Function to encrypt using Playfair Cipher
    static void encryptByPlayfairCipher(ref string str, ref string key) {
        char[,] keyT = new char[5, 5];
        removeSpaces(ref key);
        toLowerCase(ref key);
        toLowerCase(ref str);
        removeSpaces(ref str);
        prepare(ref str);
        generateKeyTable(ref key, keyT);
        encrypt(ref str, keyT);
    }

    public static void Main(string[] args) {
        string key = "Monarchy";
        string str = "instruments";
        Console.WriteLine("Key text: " + key);
        Console.WriteLine("Plain text: " + str);
        encryptByPlayfairCipher(ref str, ref key);
        Console.WriteLine("Cipher text: " + str);
    }
}
JavaScript
// Function to convert the string to lowercase
function toLowerCase(plain) {
    return plain.toLowerCase();
}

// Function to remove all spaces in a string
function removeSpaces(plain) {
    return plain.replace(/\s/g, '');
}

// Function to generate the 5x5 key square
function generateKeyTable(key, keyT) {
    let hash = Array(26).fill(0);
    for (let i = 0; i < key.length; i++) {
        if (key[i] !== 'j')
            hash[key.charCodeAt(i) - 97] = 2;
    }
    hash['j'.charCodeAt(0) - 97] = 1;

    let i = 0, j = 0;
    for (let k = 0; k < key.length; k++) {
        if (hash[key.charCodeAt(k) - 97] === 2) {
            hash[key.charCodeAt(k) - 97] -= 1;
            keyT[i][j++] = key[k];
            if (j === 5) { i++; j = 0; }
        }
    }

    for (let k = 0; k < 26; k++) {
        if (hash[k] === 0) {
            keyT[i][j++] = String.fromCharCode(k + 97);
            if (j === 5) { i++; j = 0; }
        }
    }
}

// Function to search for the characters of a digraph
// in the key square and return their position
function search(keyT, a, b, arr) {
    if (a === 'j') a = 'i';
    if (b === 'j') b = 'i';

    for (let i = 0; i < 5; i++) {
        for (let 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 make the plain text length to be even
function prepare(str) {
    if (str.length % 2 !== 0)
        str += 'z';
    return str;
}

// Function for performing the encryption
function encrypt(str, keyT) {
    let arr = Array(4);
    let result = str.split('');
    for (let i = 0; i < str.length; i += 2) {
        search(keyT, result[i], result[i + 1], arr);

        if (arr[0] === arr[2]) {
            result[i] = keyT[arr[0]][(arr[1] + 1) % 5];
            result[i + 1] = keyT[arr[0]][(arr[3] + 1) % 5];
        } else if (arr[1] === arr[3]) {
            result[i] = keyT[(arr[0] + 1) % 5][arr[1]];
            result[i + 1] = keyT[(arr[2] + 1) % 5][arr[1]];
        } else {
            result[i] = keyT[arr[0]][arr[3]];
            result[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
    return result.join('');
}

// Function to encrypt using Playfair Cipher
function encryptByPlayfairCipher(str, key) {
    key = removeSpaces(toLowerCase(key));
    str = removeSpaces(toLowerCase(str));
    str = prepare(str);

    let keyT = Array.from({ length: 5 }, () => Array(5));
    generateKeyTable(key, keyT);

    return encrypt(str, keyT);
}

let key = "Monarchy";
let str = "instruments";
console.log("Key text:", key);
console.log("Plain text:", str);
str = encryptByPlayfairCipher(str, key);
console.log("Cipher text:", str);

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.
The Algorithm consists of 2 steps: 

  1. Generate the key Square(5x5) 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.

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 -> ealgorithm to decrypt the ciphertextIf 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 1If 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 2For 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 given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// Function to convert the string to lowercase
void toLowerCase(string &plain) {
    int n = plain.size();
    for (int i = 0; i < n; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}

// Function to remove all spaces in a string
void removeSpaces(string &plain) {
    int n = plain.size();
    string temp;
    for (int i = 0; i < n; i++) {
        if (plain[i] != ' ') {
            temp += plain[i];
        }
    }
    plain = temp;
}

// Function to generate the 5x5 key square
void generateKeyTable(string &key, 
        vector<vector<char>> &keyT) {
    int n = key.size();

    // 5x5 key table
    keyT.resize(5, vector<char>(5, 0));

    // a 26 character hashmap
    // to store count of the alphabet
    vector<int> hash(26, 0);

    int i, j, k, flag = 0;
    for (i = 0; i < n; i++) {
        if (key[i] != 'j')
            hash[key[i] - 97] = 2;
    }

    hash['j' - 97] = 1;

    i = 0;
    j = 0;

    for (k = 0; k < n; k++) {
        if (hash[key[k] - 97] == 2) {
            hash[key[k] - 97] -= 1;
            keyT[i][j] = key[k];
            j++;
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }

    for (k = 0; k < 26; k++) {
        if (hash[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(vector<vector<char>> &keyT, 
        char a, char b, vector<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 decrypt
void decrypt(string &str, vector<vector<char>> &keyT) {
    int n = str.size();

    vector<int> arr(4);
    for (int i = 0; i < n; i += 2) {
        search(keyT, str[i], str[i + 1], arr);
        if (arr[0] == arr[2]) {
            str[i] = keyT[arr[0]][(arr[1] - 1 + 5) % 5];
            str[i + 1] = keyT[arr[0]][(arr[3] - 1 + 5) % 5];
        }
        else if (arr[1] == arr[3]) {
            str[i] = keyT[(arr[0] - 1 + 5) % 5][arr[1]];
            str[i + 1] = keyT[(arr[2] - 1 + 5) % 5][arr[1]];
        }
        else {
            str[i] = keyT[arr[0]][arr[3]];
            str[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
}

// Function to call decrypt
void decryptByPlayfairCipher(string &str, string &key) {
    vector<vector<char>> keyT;
    removeSpaces(key);
    toLowerCase(key);
    toLowerCase(str);
    removeSpaces(str);
    generateKeyTable(key, keyT);
    decrypt(str, keyT);
}

int main() {
    string key = "Monarchy";
    string str = "gatlmzclrqtx";
    cout << "Key text: " << key << endl;
    cout << "Plain text: " << str << endl;
    decryptByPlayfairCipher(str, key);
    cout << "Decipherred text: " << str << endl;
    return 0;
}
C
#include <stdio.h>
#include <string.h>
#include <ctype.h>

// Function to convert the string to lowercase
void toLowerCase(char *plain) {
    int n = strlen(plain);
    for (int i = 0; i < n; i++) {
        if (plain[i] > 64 && plain[i] < 91)
            plain[i] += 32;
    }
}

// Function to remove all spaces in a string
void removeSpaces(char *plain) {
    int n = strlen(plain);
    char temp[100];
    int index = 0;
    for (int i = 0; i < n; i++) {
        if (plain[i] != ' ') {
            temp[index++] = plain[i];
        }
    }
    temp[index] = '\0';
    strcpy(plain, temp);
}

// Function to generate the 5x5 key square
void generateKeyTable(char *key, char keyT[5][5]) {
    int n = strlen(key);

    int hash[26] = {0};

    for (int i = 0; i < n; i++) {
        if (key[i] != 'j')
            hash[key[i] - 97] = 2;
    }

    hash['j' - 97] = 1;

    int i = 0, j = 0, k;

    for (k = 0; k < n; k++) {
        if (hash[key[k] - 97] == 2) {
            hash[key[k] - 97] -= 1;
            keyT[i][j++] = key[k];
            if (j == 5) {
                i++;
                j = 0;
            }
        }
    }

    for (k = 0; k < 26; k++) {
        if (hash[k] == 0) {
            keyT[i][j++] = k + 97;
            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[4]) {
    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 decrypt
void decrypt(char *str, char keyT[5][5]) {
    int n = strlen(str);
    int arr[4];
    for (int i = 0; i < n; i += 2) {
        search(keyT, str[i], str[i + 1], arr);
        if (arr[0] == arr[2]) {
            str[i] = keyT[arr[0]][(arr[1] - 1 + 5) % 5];
            str[i + 1] = keyT[arr[0]][(arr[3] - 1 + 5) % 5];
        }
        else if (arr[1] == arr[3]) {
            str[i] = keyT[(arr[0] - 1 + 5) % 5][arr[1]];
            str[i + 1] = keyT[(arr[2] - 1 + 5) % 5][arr[1]];
        }
        else {
            str[i] = keyT[arr[0]][arr[3]];
            str[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
}

// Function to call decrypt
void decryptByPlayfairCipher(char *str, char *key) {
    char keyT[5][5];
    removeSpaces(key);
    toLowerCase(key);
    toLowerCase(str);
    removeSpaces(str);
    generateKeyTable(key, keyT);
    decrypt(str, keyT);
}

int main() {
    char key[100] = "Monarchy";
    char str[100] = "gatlmzclrqtx";
    printf("Key text: %s\n", key);
    printf("Plain text: %s\n", str);
    decryptByPlayfairCipher(str, key);
    printf("Decipherred text: %s\n", str);
    return 0;
}
Java
import java.util.*;

class GfG {

    // Function to convert the string to lowercase
    static void toLowerCase(StringBuilder plain) {
        for (int i = 0; i < plain.length(); i++) {
            if (plain.charAt(i) >= 65 && plain.charAt(i) <= 90)
                plain.setCharAt(i, (char)(plain.charAt(i) + 32));
        }
    }

    // Function to remove all spaces in a string
    static void removeSpaces(StringBuilder plain) {
        for (int i = 0; i < plain.length(); i++) {
            if (plain.charAt(i) == ' ') {
                plain.deleteCharAt(i);
                i--;
            }
        }
    }

    // Function to generate the 5x5 key square
    static void generateKeyTable(StringBuilder key, char[][] keyT) {
        int[] hash = new int[26];
        int n = key.length();
        for (int i = 0; i < n; i++) {
            if (key.charAt(i) != 'j')
                hash[key.charAt(i) - 97] = 2;
        }

        hash['j' - 97] = 1;

        int i = 0, j = 0, k;

        for (k = 0; k < n; k++) {
            if (hash[key.charAt(k) - 97] == 2) {
                hash[key.charAt(k) - 97]--;
                keyT[i][j++] = key.charAt(k);
                if (j == 5) {
                    i++;
                    j = 0;
                }
            }
        }

        for (k = 0; k < 26; k++) {
            if (hash[k] == 0) {
                keyT[i][j++] = (char)(k + 97);
                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) {
        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(StringBuilder str, char[][] keyT) {
        int[] arr = new int[4];
        for (int i = 0; i < str.length(); i += 2) {
            search(keyT, str.charAt(i), str.charAt(i + 1), arr);
            if (arr[0] == arr[2]) {
                str.setCharAt(i, keyT[arr[0]][(arr[1] - 1 + 5) % 5]);
                str.setCharAt(i + 1, keyT[arr[0]][(arr[3] - 1 + 5) % 5]);
            } else if (arr[1] == arr[3]) {
                str.setCharAt(i, keyT[(arr[0] - 1 + 5) % 5][arr[1]]);
                str.setCharAt(i + 1, keyT[(arr[2] - 1 + 5) % 5][arr[1]]);
            } else {
                str.setCharAt(i, keyT[arr[0]][arr[3]]);
                str.setCharAt(i + 1, keyT[arr[2]][arr[1]]);
            }
        }
    }

    // Function to call decrypt
    static void decryptByPlayfairCipher(StringBuilder str, StringBuilder key) {
        char[][] keyT = new char[5][5];
        removeSpaces(key);
        toLowerCase(key);
        toLowerCase(str);
        removeSpaces(str);
        generateKeyTable(key, keyT);
        decrypt(str, keyT);
    }

    public static void main(String[] args) {
        StringBuilder key = new StringBuilder("Monarchy");
        StringBuilder str = new StringBuilder("gatlmzclrqtx");
        System.out.println("Key text: " + key);
        System.out.println("Plain text: " + str);
        decryptByPlayfairCipher(str, key);
        System.out.println("Decipherred text: " + str);
    }
}
Python
# Function to convert the string to lowercase
def toLowerCase(plain):
    plain = list(plain)
    for i in range(len(plain)):
        if ord(plain[i]) > 64 and ord(plain[i]) < 91:
            plain[i] = chr(ord(plain[i]) + 32)
    return ''.join(plain)

# Function to remove all spaces in a string
def removeSpaces(plain):
    return ''.join([c for c in plain if c != ' '])

# Function to generate the 5x5 key square
def generateKeyTable(key, keyT):
    n = len(key)

    keyT[:] = [['' for _ in range(5)] for _ in range(5)]

    hashArr = [0] * 26

    for i in range(n):
        if key[i] != 'j':
            hashArr[ord(key[i]) - 97] = 2

    hashArr[ord('j') - 97] = 1

    i = j = 0

    for k in range(n):
        if hashArr[ord(key[k]) - 97] == 2:
            hashArr[ord(key[k]) - 97] -= 1
            keyT[i][j] = key[k]
            j += 1
            if j == 5:
                i += 1
                j = 0

    for k in range(26):
        if hashArr[k] == 0:
            keyT[i][j] = chr(k + 97)
            j += 1
            if j == 5:
                i += 1
                j = 0

# Function to search for the characters of a digraph
# in the key square and return their position
def search(keyT, a, b, arr):
    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] = i
                arr[1] = j
            elif keyT[i][j] == b:
                arr[2] = i
                arr[3] = j

# Function to decrypt
def decrypt(string, keyT):
    n = len(string)
    string = list(string)
    arr = [0] * 4
    for i in range(0, n, 2):
        search(keyT, string[i], string[i + 1], arr)
        if arr[0] == arr[2]:
            string[i] = keyT[arr[0]][(arr[1] - 1 + 5) % 5]
            string[i + 1] = keyT[arr[0]][(arr[3] - 1 + 5) % 5]
        elif arr[1] == arr[3]:
            string[i] = keyT[(arr[0] - 1 + 5) % 5][arr[1]]
            string[i + 1] = keyT[(arr[2] - 1 + 5) % 5][arr[1]]
        else:
            string[i] = keyT[arr[0]][arr[3]]
            string[i + 1] = keyT[arr[2]][arr[1]]
    return ''.join(string)

# Function to call decrypt
def decryptByPlayfairCipher(string, key):
    keyT = []
    key = removeSpaces(key)
    key = toLowerCase(key)
    string = toLowerCase(string)
    string = removeSpaces(string)
    generateKeyTable(key, keyT)
    return decrypt(string, keyT)

key = "Monarchy"
string = "gatlmzclrqtx"
print("Key text:", key)
print("Plain text:", string)
string = decryptByPlayfairCipher(string, key)
print("Decipherred text:", string)
C#
using System;
using System.Collections.Generic;

class GfG {

    // Function to convert the string to lowercase
    static void toLowerCase(ref string plain) {
        char[] chars = plain.ToCharArray();
        for (int i = 0; i < chars.Length; i++) {
            if (chars[i] > 64 && chars[i] < 91)
                chars[i] = (char)(chars[i] + 32);
        }
        plain = new string(chars);
    }

    // Function to remove all spaces in a string
    static void removeSpaces(ref string plain) {
        plain = plain.Replace(" ", "");
    }

    // Function to generate the 5x5 key square
    static void generateKeyTable(ref string key, char[,] keyT) {
        int n = key.Length;
        int[] hash = new int[26];

        for (int i = 0; i < n; i++) {
            if (key[i] != 'j')
                hash[key[i] - 97] = 2;
        }

        hash['j' - 97] = 1;

        int iRow = 0, jCol = 0;

        for (int k = 0; k < n; k++) {
            if (hash[key[k] - 97] == 2) {
                hash[key[k] - 97]--;
                keyT[iRow, jCol++] = key[k];
                if (jCol == 5) {
                    iRow++;
                    jCol = 0;
                }
            }
        }

        for (int k = 0; k < 26; k++) {
            if (hash[k] == 0) {
                keyT[iRow, jCol++] = (char)(k + 97);
                if (jCol == 5) {
                    iRow++;
                    jCol = 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) {
        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(ref string str, char[,] keyT) {
        char[] chars = str.ToCharArray();
        int n = str.Length;
        int[] arr = new int[4];
        for (int i = 0; i < n; i += 2) {
            search(keyT, chars[i], chars[i + 1], arr);
            if (arr[0] == arr[2]) {
                chars[i] = keyT[arr[0], (arr[1] - 1 + 5) % 5];
                chars[i + 1] = keyT[arr[0], (arr[3] - 1 + 5) % 5];
            }
            else if (arr[1] == arr[3]) {
                chars[i] = keyT[(arr[0] - 1 + 5) % 5, arr[1]];
                chars[i + 1] = keyT[(arr[2] - 1 + 5) % 5, arr[1]];
            }
            else {
                chars[i] = keyT[arr[0], arr[3]];
                chars[i + 1] = keyT[arr[2], arr[1]];
            }
        }
        str = new string(chars);
    }

    // Function to call decrypt
    static void decryptByPlayfairCipher(ref string str, ref string key) {
        char[,] keyT = new char[5, 5];
        removeSpaces(ref key);
        toLowerCase(ref key);
        toLowerCase(ref str);
        removeSpaces(ref str);
        generateKeyTable(ref key, keyT);
        decrypt(ref str, keyT);
    }

    public static void Main() {
        string key = "Monarchy";
        string str = "gatlmzclrqtx";
        Console.WriteLine("Key text: " + key);
        Console.WriteLine("Plain text: " + str);
        decryptByPlayfairCipher(ref str, ref key);
        Console.WriteLine("Decipherred text: " + str);
    }
}
JavaScript
// Function to convert the string to lowercase
function toLowerCase(plain) {
    return plain.toLowerCase();
}

// Function to remove all spaces in a string
function removeSpaces(plain) {
    return plain.replace(/ /g, '');
}

// Function to generate the 5x5 key square
function generateKeyTable(key, keyT) {
    let hash = new Array(26).fill(0);
    let n = key.length;

    for (let i = 0; i < n; i++) {
        if (key[i] !== 'j')
            hash[key.charCodeAt(i) - 97] = 2;
    }

    hash['j'.charCodeAt(0) - 97] = 1;

    let i = 0, j = 0;

    for (let k = 0; k < n; k++) {
        if (hash[key.charCodeAt(k) - 97] === 2) {
            hash[key.charCodeAt(k) - 97]--;
            keyT[i][j++] = key[k];
            if (j === 5) {
                i++;
                j = 0;
            }
        }
    }

    for (let k = 0; k < 26; k++) {
        if (hash[k] === 0) {
            keyT[i][j++] = String.fromCharCode(k + 97);
            if (j === 5) {
                i++;
                j = 0;
            }
        }
    }
}

// Function to search for the characters of a digraph
// in the key square and return their position
function search(keyT, a, b, arr) {
    if (a === 'j') a = 'i';
    else if (b === 'j') b = 'i';

    for (let i = 0; i < 5; i++) {
        for (let 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
function decrypt(str, keyT) {
    let arr = new Array(4);
    str = str.split('');
    for (let i = 0; i < str.length; i += 2) {
        search(keyT, str[i], str[i + 1], arr);
        if (arr[0] === arr[2]) {
            str[i] = keyT[arr[0]][(arr[1] - 1 + 5) % 5];
            str[i + 1] = keyT[arr[0]][(arr[3] - 1 + 5) % 5];
        } else if (arr[1] === arr[3]) {
            str[i] = keyT[(arr[0] - 1 + 5) % 5][arr[1]];
            str[i + 1] = keyT[(arr[2] - 1 + 5) % 5][arr[1]];
        } else {
            str[i] = keyT[arr[0]][arr[3]];
            str[i + 1] = keyT[arr[2]][arr[1]];
        }
    }
    return str.join('');
}

// Function to call decrypt
function decryptByPlayfairCipher(str, key) {
    let keyT = Array.from({ length: 5 }, () => Array(5));
    key = removeSpaces(toLowerCase(key));
    str = removeSpaces(toLowerCase(str));
    generateKeyTable(key, keyT);
    return decrypt(str, keyT);
}

let key = "Monarchy";
let str = "gatlmzclrqtx";
console.log("Key text: " + key);
console.log("Plain text: " + str);
str = decryptByPlayfairCipher(str, key);
console.log("Decipherred text: " + str);

Output
Key text: Monarchy
Plain text: gatlmzclrqtx
Decipherred text: instrumentsz

Advantages and Disadvantages

Advantages: 

  • 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.  
  • Frequency analysis thus requires more cipher text to crack the encryption. 

Disadvantages: 

  • 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. 
  • Another disadvantage is that playfair cipher is a symmetric cipher thus same key is used for both encryption and decryption. 
Comment