Keyword cipher is a form of monoalphabetic substitution. A keyword is used as the key, and it determines the letter matchings of the cipher alphabet to the plain alphabet. Repeats of letters in the word are removed, then the cipher alphabet is generated with the keyword matching to A, B, C, etc. until the keyword is used up, whereupon the rest of the ciphertext letters are used in alphabetical order, excluding those already used in the key.
Encryption:
The first line of input contains the keyword which you wish to enter. The second line of input contains the string which you have to encrypt.
Plaintext: 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 Encrypted: K R Y P T O S A B C D E F G H I J L M N Q U V W X Z
With KRYPTOS as the keyword, all As become Ks, all Bs becoming Rs, and so on. Encrypting the message “knowledge is power” using the keyword “Kryptos”:
Encrypting the message: Knowledge is Power Encoded message: IlmWjbaEb GQ NmWbp
Examples:
Input : Keyword : secret Message : Zombie Here Output : Ciphered String : ZLJEFT DTOT
Take the first example, we used "secret" keyword there. Plain Text : 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 When "secret" keyword is used, the new encrypting text becomes : Encrypting : S E C R T A B D F G H I J K L M N O P Q U V W X Y Z This means 'A' means 'S', 'B' means 'E' and 'C' means 'C' and so on. Lets encode the given message "Zombie Here" ZOMBIE HERE becomes ZLJEFT DTOT
Input : Keyword : Star War Message : Attack at dawn Output : Ciphered String : SPPSAG SP RSVJ
Few points to be noted in this method:
- All the messages are encoded in uppercase.
- Whitespace, special characters, and numbers do not take into consideration keywords although you can put them in there.
- While encrypting the message, whitespace, special characters and numbers remain unaffected.
Below is the implementation:
Keyword : Computer Message before Ciphering : GeeksforGeeks Ciphered Text : EUUDNTILEUUDN
Decryption:
To decode the message you check the position of the given message in encrypting text with the plain text.
Plaintext: 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 Encrypted: K R Y P T O S A B C D E F G H I J L M N Q U V W X Z
Message: PTYBIATLEP Deciphered Text: DECIPHERED
Now, how do we generate the deciphered string? We search for ‘P’ in Encrypted Text and compare its position with plain text letter and generate that letter. So ‘P’ becomes ‘D’, ‘T’ becomes ‘E’, ‘Y’ becomes ‘C’, and so on.
Examples:
Input : Keyword : secret Message : zljeft dtOT Output : Deciphered String : ZOMBIE HERE Input : Keyword : joker0O7hack123 Message : QjTijl Output : Deciphered String : BATMAN
Below is the implementation:
Example 1
// CPP program for decoding the string // which generate using classical cipher #include <bits/stdc++.h> using namespace std;
// Original Set of letters string plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
// Function generates the encoded text string encoder(string key) { string encoded = "" ;
bool arr[26] = { 0 };
// This loop inserts the keyword
// at the start of the encoded string
for ( int i = 0; i < key.size(); i++) {
if (key[i] >= 'A' && key[i] <= 'Z' ) {
// To check whether the character is inserted
// earlier in the encoded string or not
if (arr[key[i] - 65] == 0) {
encoded += key[i];
arr[key[i] - 65] = 1;
}
}
else if (key[i] >= 'a' && key[i] <= 'z' ) {
if (arr[key[i] - 97] == 0) {
encoded += key[i] - 32;
arr[key[i] - 97] = 1;
}
}
}
// This loop inserts the remaining
// characters in the encoded string.
for ( int i = 0; i < 26; i++) {
if (arr[i] == 0) {
arr[i] = 1;
encoded += char (i + 65);
}
}
return encoded;
} // This function will decode the message string decipheredIt(string msg, string encoded) { // Hold the position of every character (A-Z)
// from encoded string
map< char , int > enc;
for ( int i = 0; i < encoded.size(); i++) {
enc[encoded[i]] = i;
}
string decipher = "" ;
// This loop deciphered the message.
// Spaces, special characters and numbers remain same.
for ( int i = 0; i < msg.size(); i++) {
if (msg[i] >= 'a' && msg[i] <= 'z' ) {
int pos = enc[msg[i] - 32];
decipher += plaintext[pos];
}
else if (msg[i] >= 'A' && msg[i] <= 'Z' ) {
int pos = enc[msg[i]];
decipher += plaintext[pos];
}
else {
decipher += msg[i];
}
}
return decipher;
} // Driver code int main()
{ // Hold the Keyword
string key;
key = "Computer" ;
cout << "Keyword : " << key << endl;
// Function call to generate encoded text
string encoded = encoder(key);
// Message that need to decode
string message = "EUUDN TIL EUUDN" ;
cout << "Message before Deciphering : " << message
<< endl;
// Function call to print deciphered text
cout << "Ciphered Text : "
<< decipheredIt(message, encoded) << endl;
return 0;
} |
// Java program for decoding the string // using classical cipher import java.util.HashMap;
import java.util.Map;
class GFG
{ // Function generates the encoded text
public static String encoder( char [] key)
{
String encoded = "" ;
// This array represents the
// 26 letters of alphabets
boolean [] arr = new boolean [ 26 ];
// This loop inserts the keyword
// at the start of the encoded string
for ( int i = 0 ; i < key.length; i++)
{
if (key[i] >= 'A' && key[i] <= 'Z' )
{
// To check whether the character is inserted
// earlier in the encoded string or not
if (arr[key[i] - 65 ] == false )
{
encoded += ( char ) key[i];
arr[key[i] - 65 ] = true ;
}
}
else if (key[i] >= 'a' && key[i] <= 'z' )
{
if (arr[key[i] - 97 ] == false )
{
encoded += ( char ) (key[i] - 32 );
arr[key[i] - 97 ] = true ;
}
}
}
// This loop inserts the remaining
// characters in the encoded string.
for ( int i = 0 ; i < 26 ; i++)
{
if (arr[i] == false )
{
arr[i] = true ;
encoded += ( char ) (i + 65 );
}
}
return encoded;
}
// This function will decode the message
public static String decipheredIt(String msg, String input)
{
// Original Set of letters
String plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
String decipher = "" ;
// Hold the position of every character (A-Z) from encoded string
Map<Character, Integer> enc = new HashMap<>();
for ( int i = 0 ; i < input.length(); i++)
{
enc.put(input.charAt(i), i);
}
// This loop deciphered the message.
// Spaces, special characters and numbers remain same.
for ( int i = 0 ; i < msg.length(); i++)
{
if (msg.charAt(i) >= 'a' && msg.charAt(i) <= 'z' )
{
int pos = enc.get(( char )(msg.charAt(i)- 32 ));
decipher += plaintext.charAt(pos);
}
else if (msg.charAt(i) >= 'A' && msg.charAt(i) <= 'Z' )
{
int pos = enc.get(msg.charAt(i));
decipher += plaintext.charAt(pos);
}
else
{
decipher += msg.charAt(i);
}
}
return decipher;
}
// Driver code
public static void main(String[] args)
{
// Hold the Keyword
String key;
key = "Computer" ;
System.out.println( "Keyword : " + key);
// Function call to generate encoded text
String decoded = encoder(key.toCharArray());
// Message that need to encode
String message = "EUUDN TIL EUUDN" ;
System.out.println( "Message before Deciphering : " + message);
// Function call to print ciphered text
System.out.println( "Ciphered Text : " + decipheredIt(message,
decoded));
}
} // This code is contributed by javierdsv |
# Python program for decoding the string # using classical cipher import string
# stores all upper case alphabets all_alphabets = list (string.ascii_uppercase)
# Function generates the encoded text def encoder(key):
encoded = ""
# This array represents the
# 26 letters of alphabets
arr = [ False ] * 26
# This loop inserts the keyword
# at the start of the encoded string
for i in range ( len (key)):
if key[i] > = 'A' and key[i] < = 'Z' :
# To check whether the character is inserted
# earlier in the encoded string or not
if arr[ ord (key[i]) - 65 ] = = False :
encoded + = key[i]
arr[ ord (key[i]) - 65 ] = True
elif key[i] > = 'a' and key[i] < = 'z' :
if arr[ ord (key[i]) - 97 ] = = False :
encoded + = chr ( ord (key[i]) - 32 )
arr[ ord (key[i]) - 97 ] = True
# This loop inserts the remaining
# characters in the encoded string.
for i in range ( 26 ):
if arr[i] = = False :
arr[i] = True
encoded + = ( chr (i + 65 ))
return encoded
# This function will decode the message def decipheredIt(msg, encoded):
# Original Set of letters
plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
decipher = ""
# Hold the position of every character (A-Z) from encoded string
enc = {}
for i in range ( len (encoded)):
enc[encoded[i]] = i
# This loop deciphered the message.
# Spaces, special characters and numbers remain same.
for i in range ( len (msg)):
if msg[i] > = 'a' and msg[i] < = 'z' :
pos = enc.get(( chr )(msg[i] - 32 ))
decipher + = plaintext[pos]
elif msg[i] > = 'A' and msg[i] < = 'Z' :
pos = enc.get(msg[i])
decipher + = plaintext[pos]
else :
decipher + = msg[i]
return decipher
# Hold the Keyword key = "Computer"
print ( "Keyword : " + key)
# Function call to generate encoded text decoded = encoder( list (key))
# Message that need to encode message = "EUUDN TIL EUUDN"
print ( "Message before Deciphering : " + message)
# Function call to print ciphered text print ( "Ciphered Text : " + decipheredIt(message, decoded))
# This code is contributed by arorapranay. |
using System;
using System.Collections.Generic;
class GFG {
public static String encoder( char [] key)
{
String encoded = "" ;
// This array represents the
// 26 letters of alphabets
bool [] arr = new bool [26];
// This loop inserts the keyword
// at the start of the encoded string
for ( int i = 0; i < key.Length; i++) {
if (key[i] >= 'A' && key[i] <= 'Z' ) {
// To check whether the character is
// inserted earlier in the encoded string or
// not
if (arr[key[i] - 65] == false ) {
encoded += ( char )key[i];
arr[key[i] - 65] = true ;
}
}
else if (key[i] >= 'a' && key[i] <= 'z' ) {
if (arr[key[i] - 97] == false ) {
encoded += ( char )(key[i] - 32);
arr[key[i] - 97] = true ;
}
}
}
// This loop inserts the remaining
// characters in the encoded string.
for ( int i = 0; i < 26; i++) {
if (arr[i] == false ) {
arr[i] = true ;
encoded += ( char )(i + 65);
}
}
return encoded;
}
// This function will decode the message
public static String decipheredIt(String msg,
String input)
{
// Original Set of letters
String plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
String decipher = "" ;
// Hold the position of every character (A-Z) from
// encoded string
Dictionary< char , int > enc
= new Dictionary< char , int >();
for ( int i = 0; i < input.Length; i++) {
enc.Add(input[i], i);
}
// This loop deciphered the message.
// Spaces, special characters and numbers remain
// same.
for ( int i = 0; i < msg.Length; i++) {
if (msg[i] >= 'a' && msg[i] <= 'z' ) {
int pos = enc[( char )(msg[i] - 32)];
decipher += plaintext[pos];
}
else if (msg[i] >= 'A' && msg[i] <= 'Z' ) {
int pos = enc[msg[i]];
decipher += plaintext[pos];
}
else {
decipher += msg[i];
}
}
return decipher;
}
static void Main()
{
// Hold the Keyword
String key;
key = "Computer" ;
Console.WriteLine( "Keyword : " + key);
// Function call to generate encoded text
String decoded = encoder(key.ToCharArray());
// Message that need to encode
String message = "EUUDN TIL EUUDN" ;
Console.WriteLine( "Message before Deciphering : "
+ message);
// Function call to print ciphered text
Console.WriteLine( "Ciphered Text : "
+ decipheredIt(message, decoded));
}
} // This code is contributed by Pranay Arora |
// Javascript program for decoding the string // which generate using classical cipher // Original Set of letters let plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
// Function generates the encoded text function encoder(key)
{ let encoded = "" ;
let arr = new Array(26).fill(0);
// This loop inserts the keyword
// at the start of the encoded string
for (let i = 0; i < key.length; i++) {
if (key[i] >= 'A' && key[i] <= 'Z' ) {
// To check whether the character is inserted
// earlier in the encoded string or not
if (arr[key.charCodeAt(i) - 65] == 0) {
encoded += key[i];
arr[key.charCodeAt(i) - 65] = 1;
}
}
else if (key[i] >= 'a' && key[i] <= 'z' ) {
if (arr[key.charCodeAt(i) - 97] == 0) {
encoded += String.fromCharCode((key.charCodeAt(i) - 32));
arr[key.charCodeAt(i) - 97] = 1;
}
}
}
// This loop inserts the remaining
// characters in the encoded string.
for (let i = 0; i < 26; i++) {
if (arr[i] == 0) {
arr[i] = 1;
encoded += String.fromCharCode(65+i);
}
}
return encoded;
} // This function will decode the message function decipheredIt(msg, encoded)
{ // Hold the position of every character (A-Z)
// from encoded string
let enc = new Map();
for (let i = 0; i < encoded.length; i++) {
enc[encoded[i]] = i;
}
let decipher = "" ;
// This loop deciphered the message.
// Spaces, special characters and numbers remain same.
for (let i = 0; i < msg.length; i++) {
if (msg[i] >= 'a' && msg[i] <= 'z' ) {
let pos = enc[msg.charCodeAt(i) - 32];
decipher += plaintext[pos];
}
else if (msg[i] >= 'A' && msg[i] <= 'Z' ) {
let pos = enc[msg[i]];
decipher += plaintext[pos];
}
else {
decipher += msg[i];
}
}
return decipher;
} // Driver code // Hold the Keyword
let key;
key = "Computer" ;
console.log( "Keyword : " , key );
// Function call to generate encoded text
let encoded = encoder(key);
// Message that need to decode
let message = "EUUDN TIL EUUDN" ;
console.log( "Message before Deciphering : " , message);
// Function call to print deciphered text
console.log( "Ciphered Text : " , decipheredIt(message, encoded));
// This code is contributed by poojaagarwal2.
|
Keyword : Computer Message before Deciphering : EUUDN TIL EUUDN Ciphered Text : GEEKS FOR GEEKS
Example 2
# Python Program for Decoding the String # using Classical Cipher import string
# stores all upper case alphabets all_alphabets = list (string.ascii_uppercase)
keyword = "Star War"
keyword1 = keyword.upper()
ciphertext = "SPPSAG SP RSVJ"
# converts message to list ct = []
for i in ciphertext:
ct.append(i.upper())
# removes default elements def duplicates( list ):
key = []
for i in list :
if i not in key:
key.append(i)
return key
keyword1 = duplicates(keyword1)
# Stores the encryption list encrypting = duplicates(keyword1 + all_alphabets)
# removes spaces from the encryption list for i in encrypting:
if (i = = ' ' ):
encrypting.remove( ' ' )
# maps each element of the message to the encryption list and stores it in ciphertext message = ""
for i in range ( len (ct)):
if (ct[i] ! = ' ' ):
message = message + all_alphabets[encrypting.index(ct[i])]
else :
message = message + ' '
print ( "Keyword : " , keyword)
print ( "Ciphered Text : " , ciphertext)
print ( "Message before Ciphering : " , message)
|
// JavaScript code for the above approach const all_alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .split( '' );
const keyword = "Star War" ;
let keyword1 = keyword.toUpperCase(); const ciphertext = "SPPSAG SP RSVJ" ;
// converts message to list const ct = ciphertext.toUpperCase().split( '' );
// removes default elements const duplicates = (list) => { let key = [];
for (let i = 0; i < list.length; i++) {
if (!key.includes(list[i])) {
key.push(list[i]);
}
}
return key;
} keyword1 = duplicates(keyword1); // Stores the encryption list const encrypting = duplicates(keyword1.concat(all_alphabets)); // removes spaces from the encryption list for (let i = 0; i < encrypting.length; i++) {
if (encrypting[i] === ' ' ) {
encrypting.splice(i, 1);
}
} // maps each element of the message to the encryption list and stores it in ciphertext let message = "" ;
for (let i = 0; i < ct.length; i++) {
if (ct[i] !== ' ' ) {
message = message + all_alphabets[encrypting.indexOf(ct[i])];
} else {
message = message + ' ' ;
}
} console.log( "Keyword : " , keyword);
console.log( "Ciphered Text : " , ciphertext);
console.log( "Message before Ciphering : " , message);
// This code is contributed by lokeshpotta20. |
#include <bits/stdc++.h> int main()
{ // all alphabets
std::vector< char > all_alpha{
'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'
};
std::string keyword = "Star War" ;
std::transform(keyword.begin(), keyword.end(),
keyword.begin(), :: toupper );
std::vector< char > keyword1;
// remove duplicate elements
for ( char c : keyword) {
if (std::find(keyword1.begin(), keyword1.end(), c)
== keyword1.end()) {
keyword1.push_back(c);
}
}
// convert ciphertext to list
std::string ciphertext = "SPPSAG SP RSVJ" ;
std::transform(ciphertext.begin(), ciphertext.end(),
ciphertext.begin(), :: toupper );
std::vector< char > ct;
for ( char c : ciphertext) {
if (c != ' ' ) {
ct.push_back(c);
}
}
// stores the encryption list
std::vector< char > encrypting = keyword1;
for ( char c : all_alpha) {
if (std::find(encrypting.begin(), encrypting.end(),
c)
== encrypting.end()) {
encrypting.push_back(c);
}
}
// removes spaces from the encryption list
encrypting.erase(std:: remove (encrypting.begin(),
encrypting.end(), ' ' ),
encrypting.end());
// maps each element of the message to the encryption
// list and stores it in ciphertext
std::string message;
for ( char c : ct) {
if (c != ' ' ) {
auto it = std::find(encrypting.begin(),
encrypting.end(), c);
int index
= std::distance(encrypting.begin(), it);
message += all_alpha[index];
}
else {
message += ' ' ;
}
}
std::cout << "Keyword : " << keyword << std::endl;
std::cout << "Ciphered Text : " << ciphertext
<< std::endl;
std::cout << "Message before Ciphering : " << message
<< std::endl;
return 0;
} |
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
// all alphabets
List<Character> all_alpha = new ArrayList<>(Arrays.asList(
'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'
));
String keyword = "Star War" ;
keyword = keyword.toUpperCase();
List<Character> keyword1 = new ArrayList<>();
// remove duplicate elements
for ( char c : keyword.toCharArray()) {
if (!keyword1.contains(c)) {
keyword1.add(c);
}
}
// convert ciphertext to list
String ciphertext = "SPPSAG SP RSVJ" ;
ciphertext = ciphertext.toUpperCase();
List<Character> ct = new ArrayList<>();
for ( char c : ciphertext.toCharArray()) {
if (c != ' ' ) {
ct.add(c);
}
}
// stores the encryption list
List<Character> encrypting = new ArrayList<>(keyword1);
for ( char c : all_alpha) {
if (!encrypting.contains(c)) {
encrypting.add(c);
}
}
// removes spaces from the encryption list
encrypting.remove(Character.valueOf( ' ' ));
// list and stores it in ciphertext
StringBuilder message = new StringBuilder();
for ( char c : ct) {
if (c != ' ' ) {
int index = encrypting.indexOf(c);
message.append(all_alpha.get(index));
} else {
message.append( ' ' );
}
}
System.out.println( "Keyword : " + keyword);
System.out.println( "Ciphered Text : " + ciphertext);
System.out.println( "Message before Ciphering : " + message);
}
} |
using System;
using System.Collections.Generic;
using System.Linq;
class MainClass {
public static void Main( string [] args)
{
string allAlphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
string keyword = "Star War" ;
string keyword1 = keyword.ToUpper();
string ciphertext = "SPPSAG SP RSVJ" ;
// convert message to list
List< char > ct = new List< char >();
foreach ( char c in ciphertext)
{
ct.Add(Char.ToUpper(c));
}
// remove duplicates from keyword
List< char > keywordList
= new List< char >(keyword1.Distinct());
// create encryption list
List< char > encrypting
= keywordList.Concat(allAlphabets)
.Distinct()
.ToList();
// remove spaces from the encryption list
encrypting.Remove( ' ' );
// map each element of the message to the encryption
// list and store it in message
string message = "" ;
foreach ( char c in ct)
{
if (c != ' ' ) {
message
+= allAlphabets[encrypting.IndexOf(c)];
}
else {
message += " " ;
}
}
Console.WriteLine( "Keyword : " + keyword);
Console.WriteLine( "Ciphered Text : " + ciphertext);
Console.WriteLine( "Message before Ciphering : "
+ message);
}
} |
('Keyword : ', 'Star War') ('Ciphered Text : ', 'SPPSAG SP RSVJ') ('Message before Ciphering : ', 'ATTACK AT DAWN')
Note: One can improve this Classical Cipher: Keyword also. Here we are only taking A-Z in plain text. You can take uppercase, lowercase, and numbers also into consideration.
Ways to attack a keyword cipher:
The best ways to attack a keyword cipher without knowing the keyword are through the known-plaintext attack, frequency analysis, and discovery of the keyword (often a cryptanalyst will combine all three techniques). Keyword discovery allows immediate decryption since the table can be made immediately.