Keyword Cipher

Introduction

Keyword Cipher is another method of encrypting alphabetic text. It is a type of monoalphabetic substitution cipher. Monoalphabetic means an alphabet in plain text is mapped to one alphabet in the ciphertext. For example, if the plain text contains multiple occurrences of ‘A’ then all occurrences of ‘A’ are substituted by the same alphabet in the ciphertext.

Encryption

Suppose the plain text is

“HELLO WORLD”

Next, we have to choose a keyword. The keyword should not have any repeated alphabets. Let the keyword be

“DRAGON”

Next, we map each alphabet in plain text to the alphabet in the ciphertext. The starting N alphabets of plain text are mapped to the alphabet of the keyword where N is the length of the keyword.

keyword cipher
plaintext alphabet mapped to keyword

To fill the rest of the alphabets in the ciphertext, we use the remaining alphabets in chronological order. We skip over those alphabets that are already present in the ciphertext. See the figure shown below.

keyword cipher
map plaintext to ciphertext alphabets

We use the above mapping to encrypt the plain text.

Plain Text: “HELLO WORLD”
Keyword: “DRAGON”
Cipher Text: “COIIL WLQIG”

Decryption

Decryption is very simple. We map plaintext alphabets to ciphertext alphabets using the keyword then use the reverse mapping to convert the ciphertext to plaintext.

Implementation

Note: The code assumes that the plaintext/ciphertext only contains English alphabets from ‘A’ to ‘Z’.

#include <iostream>
#include <string>
#include <map>
using namespace std;

string encrypt(string plainText, string keyword)
{
	int i;
	char j, t;
	map<char, char> mapping; // map to store plaintext and ciphertext alphabet mapping 
	string cipherText;

	j = 'A';

	// mapping starting alphabets to alphabet of the keyword
	for (i = 0; i < keyword.length(); ++i)
	{
		mapping[j++] = keyword[i];
	}

	// mapping the remaining alphabets to the alphabets not present in keyword in
	// chronological order
	for (t = 'A'; t <= 'Z'; ++t)
	{
		// checking if the character t is already mapped or not
		if (keyword.find(t) >= keyword.length())
		{
			mapping[j++] = t;
		}
	}

	cipherText = "";
	for (i = 0; i < plainText.length(); ++i)
	{
		cipherText += mapping[plainText[i]];
	}

	return cipherText;

}

string decrypt(string cipherText, string keyword)
{
	int i;
	char j, t;
	map<char, char> mapping; // map to store plaintext to ciphertext alphabet mapping 
	map<char, char> r_mapping; // map to store cipherText to plaintext alphabet mapping
	string plainText;

	j = 'A';

	// mapping starting alphabets to alphabet of the keyword
	for (i = 0; i < keyword.length(); ++i)
	{
		mapping[j++] = keyword[i];
	}

	// mapping the remaining alphabets to the alphabets not present in keyword in
	// chronological order
	for (t = 'A'; t <= 'Z'; ++t)
	{
		// checking if the character t is already mapped or not
		if (keyword.find(t) >= keyword.length())
		{
			mapping[j++] = t;
		}
	}

	for (t = 'A'; t <= 'Z'; ++t)
	{
		r_mapping[mapping[t]] = t;
	}

	plainText = "";
	for (i = 0; i < cipherText.length(); ++i)
	{
		plainText += r_mapping[cipherText[i]];
	}

	return plainText;

}

int main()
{

	string plainText, cipherText, keyword;

	cout << "*******ENCRYPTION********" << endl;
	cout << "Enter Plain Text: ";
	cin >> plainText;
	cout << "Enter Keyword: ";
	cin >> keyword;
	cipherText = encrypt(plainText, keyword);
	cout << "Cipher Text: " << cipherText << endl;;

	cout << "*******DECRYPTION********" << endl;
	cout << "Enter Cipher Text: ";
	cin >> cipherText;
	cout << "Enter Keyword: ";
	cin >> keyword;
	plainText = decrypt(cipherText, keyword);
	cout << "Cipher Text: " << plainText;

	return 0;
}

Output

*******ENCRYPTION********
Enter Plain Text: HELLOWORLD
Enter Keyword: DRAGON
Cipher Text: COIILWLQIG

*******DECRYPTION********
Enter Cipher Text: COIIWLQIG
Enter Keyword: DRAGON
Cipher Text: HELLWORLD

Read

  1. Vigenere Cipher

Leave a Comment

Your email address will not be published.