Introduction
Vigenere Cipher is a method of encrypting alphabetic text. It is a polyalphabetic substitution cipher. Polyalphabetic substitution means that an alphabet in plain text is mapped to multiple substitution alphabets.
Vigenere cipher is an evolution of Caesar cipher. In Caesar cipher, we shift the alphabets of the plain text by a fixed number of positions. For example, in a Caesar cipher with shift value 4, ‘A’ becomes ‘E’, ‘B’ becomes ‘F’, and so on. Vigenere cipher uses Caesar cipher with all possible shift values.
To encrypt/decrypt plain text using Vigenere cipher, we use a table known as Vigenere square, Vigenere table, or tabula recta. The table contains 26 rows. Each row contains 26 alphabets, shifted one position to the left in a cyclic manner as we progress down the rows. For example, the first row contains A, B, C, … Z. The second row contains B, C, D, … Z, A, and so on.
Encryption
Suppose the plain text is
“HELLO WORLD”
Now we have to choose a key. If the length of the key is shorter than the plain text, then we repeat the key until its length becomes equal to the plain text. Suppose the input key is “SNAP”. The key for the given plain text will be
“SNAPSNAPSN”
Next, we pair the characters of the plain text with the corresponding character of the key as shown below.

Note that we only pair alphabets from ‘A’ to ‘Z’ with the key. Special characters and black spaces are ignored.
We use these pairs to find ciphertext. For example, the first pair is { plain text: ‘H’, key: ‘S’ }. We select the row that starts with the key alphabet ‘S’ and the column that starts with the plain text alphabet ‘H’. The letter at the intersection is the enciphered letter.
The pair { plain text: ‘H’, key: ‘S’ } intersect at ‘Z’. Thus, we replace ‘H’ with ‘Z’. In this way, we find the enciphered letters for all the alphabets of the plain text.

Implementation
#include<iostream> using namespace std; void createVigenereTable(char v_table[][26]) { int i, j; for (j = 0; j < 26; ++j) v_table[0][j] = 'A' + j; for (i = 1; i < 26; ++i) { for (j = 0; j < 26; ++j) { v_table[i][j] = (v_table[i - 1][j] - 'A' + 1) % 26 + 'A'; } } } string encryptVigenereCipher(string plainText, string key, char v_table[][26]) { int i, j; string cipherText = ""; while (key.length() < plainText.length()) key += key; for (i = 0, j = 0; i < plainText.length(); ++i) { if (plainText[i] >= 'A' && plainText[i] <= 'Z') { cipherText += v_table[key[j] - 'A'][plainText[i] - 'A']; ++j; } else { cipherText += plainText[i]; } } return cipherText; } int main() { int i, j; string plainText, cipherText, key; char v_table[26][26]; createVigenereTable(v_table); cout << "\nVIGENERE TABLE\n\n"; for (i = 0; i < 26; ++i) { for (j = 0; j < 26; ++j) { cout << v_table[i][j] << ' '; } cout << endl; } cout << endl; cout << "Enter Plain Text: "; getline(std::cin, plainText); // we are using getline as input might contain spaces cout << "Enter Key: "; cin >> key; cipherText = encryptVigenereCipher(plainText, key, v_table); cout << "The Cipher Text is: " << cipherText; }
Output
VIGENERE TABLE A B C D E F G H I J K L M N O P Q R S T U V W X Y Z B C D E F G H I J K L M N O P Q R S T U V W X Y Z A C D E F G H I J K L M N O P Q R S T U V W X Y Z A B D E F G H I J K L M N O P Q R S T U V W X Y Z A B C E F G H I J K L M N O P Q R S T U V W X Y Z A B C D F G H I J K L M N O P Q R S T U V W X Y Z A B C D E G H I J K L M N O P Q R S T U V W X Y Z A B C D E F H I J K L M N O P Q R S T U V W X Y Z A B C D E F G I J K L M N O P Q R S T U V W X Y Z A B C D E F G H J K L M N O P Q R S T U V W X Y Z 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 A B C D E F G H I J L M N O P Q R S T U V W X Y Z A B C D E F G H I J K M N O P Q R S T U V W X Y Z A B C D E F G H I J K L N O P Q R S T U V W X Y Z A B C D E F G H I J K L M O P Q R S T U V W X Y Z A B C D E F G H I J K L M N P Q R S T U V W X Y Z A B C D E F G H I J K L M N O Q R S T U V W X Y Z A B C D E F G H I J K L M N O P R S T U V W X Y Z A B C D E F G H I J K L M N O P Q S T U V W X Y Z A B C D E F G H I J K L M N O P Q R T U V W X Y Z A B C D E F G H I J K L M N O P Q R S U V W X Y Z A B C D E F G H I J K L M N O P Q R S T V W X Y Z A B C D E F G H I J K L M N O P Q R S T U W X Y Z A B C D E F G H I J K L M N O P Q R S T U V X Y Z A B C D E F G H I J K L M N O P Q R S T U V W Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Enter Plain Text: HELLO WORLD Enter Key: SNAP The Cipher Text is: ZRLAG JOGDQ
Decryption
Suppose the cipher text is
“ZRLAG JOGDQ”
Let the key be “SNAP”. We will make the length of key equal to the cipher text.
“SNAPSNAPSN”
Next, pair each character of cipher text with the corresponding character of the key.

Consider the first pair { ciphertext: ‘Z’, key: ‘S’ }. Go to the row starting with the key character ‘S’. Then search for the ciphertext character ‘Z’ in that row. The column label of ‘Z’ is the deciphered character.
The column label of ‘Z’ in the row that starts with ‘S’ is ‘H’. Thus, we replace ‘Z’ with ‘H’. In this way, we find deciphered letters for all characters of the ciphertext.

Implementation
#include<iostream> using namespace std; void createVigenereTable(char v_table[][26]) { int i, j; for (j = 0; j < 26; ++j) v_table[0][j] = 'A' + j; for (i = 1; i < 26; ++i) { for (j = 0; j < 26; ++j) { v_table[i][j] = (v_table[i - 1][j] - 'A' + 1) % 26 + 'A'; } } } string decryptVigenereCipher(string cipherText, string key, char v_table[][26]) { int i, j, k; string plainText = ""; while (key.length() < cipherText.length()) key += key; // j: is used to index key character for (i = 0, j = 0; i < cipherText.length(); ++i) { if (cipherText[i] >= 'A' && cipherText[i] <= 'Z') { for (k = 0; k < 26; ++k) { if (v_table[key[j] - 'A'][k] == cipherText[i]) { plainText += ('A' + k); ++j; break; } } } else { plainText += cipherText[i]; } } return plainText; } int main() { int i, j; string plainText, cipherText, key; char v_table[26][26]; createVigenereTable(v_table); cout << "Enter Cipher Text: "; getline(std::cin, cipherText); cout << "Enter Key: "; cin >> key; plainText = decryptVigenereCipher(cipherText, key, v_table); cout << "The Plain Text is: " << plainText; }
Output
Enter Cipher Text: ZRLAG JOGDQ Enter Key: SNAP The Plain Text is: HELLO WORLD
Encryption/Decryption without Vigenere Table
In the above programs, we are first creating the Vigenere table then using it to encrypt/decrypt date. But we can implement Vigenere cipher without storing table. Let
Implementation
#include<iostream> using namespace std; string encrypt(string plainText, string key) { int i, j; string cipherText = ""; while (key.length() < plainText.length()) key += key; // j: is used to index key characer for (i = 0, j = 0; i < plainText.length(); ++i) { if (plainText[i] >= 'A' && plainText[i] <= 'Z') { cipherText += ((plainText[i] - 'A') + (key[j] - 'A')) % 26 + 'A'; ++j; } else { cipherText += plainText[i]; } } return cipherText; } string decrypt(string cipherText, string key) { int i, j; string plainText = ""; while (key.length() < cipherText.length()) key += key; // j: is used to index key characer for (i = 0, j = 0; i < cipherText.length(); ++i) { if (cipherText[i] >= 'A' && cipherText[i] <= 'Z') { plainText += ((cipherText[i] - 'A') - (key[j] - 'A') + 26) % 26 + 'A'; ++j; } else { plainText += cipherText[i]; } } return plainText; } int main() { string plainText, cipherText, key; cout << "Enter Plain Text: "; getline(std::cin, plainText); cout << "Enter Key: "; cin >> key; cipherText = encrypt(plainText, key); cout << "The Cipher Text is: " << cipherText << endl; cout << "Enter Cipher Text: "; cin.clear(); cin.sync(); getline(std::cin, cipherText); cout << "Enter Key: "; cin >> key; plainText = decrypt(cipherText, key); cout << "The Plain Text is: " << plainText; }
Output
Enter Plain Text: HELLO WORLD Enter Key: SNAP The Cipher Text is: ZRLAG JOGDQ Enter Cipher Text: ZRLAG JOGDQ Enter Key: SNAP The Plain Text is: HELLO WORLD
References