Hiding some data is known as encryption. When plain text is encrypted it becomes unreadable and is known as ciphertext. In a Substitution cipher, any character of plain text from the given fixed set of characters is substituted by some other character from the same set depending on a key. For example with a shift of 1, A would be replaced by B, B would become C, and so on.
Note: Special case of Substitution cipher is known as Caesar cipher where the key is taken as 3.
Mathematical representation
The encryption can be represented using modular arithmetic by first transforming the letters into numbers, according to the scheme, A = 0, B = 1,…, Z = 25. Encryption of a letter by a shift n can be described mathematically as.

(Encryption Phase with shift n)

(Decryption Phase with shift n)

Examples:
Plain Text: I am studying Data Encryption
Key: 4
Output: M eq wxyhCmrk Hexe IrgvCtxmsr
Plain Text: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Key: 4
Output: EFGHIJKLMNOPQRSTUVWXYZabcd
Algorithm for Substitution Cipher:
Input:
- A String of both lower and upper case letters, called PlainText.
- An Integer denoting the required key.
Procedure:
- Create a list of all the characters.
- Create a dictionary to store the substitution for all characters.
- For each character, transform the given character as per the rule, depending on whether we’re encrypting or decrypting the text.
- Print the new string generated.
Below is the implementation.
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
string all_letrs = "abcdefghijklmnopqrstuvwxyzABCDEFGHI"
"JKLMNOPQRSTUVWXYZ" ;
map< char , char > dict1;
int key = 4;
for ( int i = 0; i < all_letrs.length(); i++) {
dict1[all_letrs[i]]
= all_letrs[(i + key) % all_letrs.length()];
}
string plain_txt = "I am studying Data Encryption" ;
string cipher_txt;
for ( char & c : plain_txt) {
if (all_letrs.find(c) != string::npos) {
cipher_txt += dict1;
}
else {
cipher_txt += c;
}
}
cout << "Cipher Text is: " << cipher_txt << endl;
map< char , char > dict2;
for ( int i = 0; i < all_letrs.length(); i++) {
dict2[all_letrs[i]]
= all_letrs[(i - key) % all_letrs.length()];
}
string decrypt_txt;
for ( char & c : cipher_txt) {
if (all_letrs.find(c) != string::npos) {
decrypt_txt += dict2;
}
else {
decrypt_txt += c;
}
}
cout << "Recovered plain text : " << decrypt_txt
<< endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
public class CaesarCipher {
public static void main(String[] args) {
String allLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHI" + "JKLMNOPQRSTUVWXYZ" ;
Map<Character, Character> dict1 = new HashMap<>();
int key = 4 ;
for ( int i = 0 ; i < allLetters.length(); i++) {
dict1.put(allLetters.charAt(i),
allLetters.charAt((i + key) % allLetters.length()));
}
String plainText = "I am studying Data Encryption" ;
StringBuilder cipherText = new StringBuilder();
for ( char c : plainText.toCharArray()) {
if (allLetters.indexOf(c) != - 1 ) {
cipherText.append(dict1.get(c));
} else {
cipherText.append(c);
}
}
System.out.println( "Cipher Text is: " + cipherText);
Map<Character, Character> dict2 = new HashMap<>();
for ( int i = 0 ; i < allLetters.length(); i++) {
dict2.put(allLetters.charAt(i),
allLetters.charAt((i - key + allLetters.length()) % allLetters.length()));
}
StringBuilder decryptedText = new StringBuilder();
for ( char c : cipherText.toString().toCharArray()) {
if (allLetters.indexOf(c) != - 1 ) {
decryptedText.append(dict2.get(c));
} else {
decryptedText.append(c);
}
}
System.out.println( "Recovered plain text: " + decryptedText);
}
}
|
Python3
import string
all_letters = string.ascii_letters
dict1 = {}
key = 4
for i in range ( len (all_letters)):
dict1[all_letters[i]] = all_letters[(i + key) % len (all_letters)]
plain_txt = "I am studying Data Encryption"
cipher_txt = []
for char in plain_txt:
if char in all_letters:
temp = dict1[char]
cipher_txt.append(temp)
else :
temp = char
cipher_txt.append(temp)
cipher_txt = "".join(cipher_txt)
print ( "Cipher Text is: " ,cipher_txt)
dict2 = {}
for i in range ( len (all_letters)):
dict2[all_letters[i]] = all_letters[(i - key) % ( len (all_letters))]
decrypt_txt = []
for char in cipher_txt:
if char in all_letters:
temp = dict2[char]
decrypt_txt.append(temp)
else :
temp = char
decrypt_txt.append(temp)
decrypt_txt = "".join(decrypt_txt)
print ( "Recovered plain text :" , decrypt_txt)
|
C#
using System;
using System.Collections.Generic;
using System.Text;
namespace SubstitutionCipher
{
class Program
{
static void Main( string [] args)
{
string allLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHI" + "JKLMNOPQRSTUVWXYZ" ;
Dictionary< char , char > dict1 = new Dictionary< char , char >();
int key = 4;
for ( int i = 0; i < allLetters.Length; i++)
{
dict1.Add(allLetters[i],
allLetters[(i + key) % allLetters.Length]);
}
string plainText = "I am studying Data Encryption" ;
StringBuilder cipherText = new StringBuilder();
foreach ( char c in plainText)
{
if (allLetters.IndexOf(c) != -1)
{
cipherText.Append(dict1);
}
else
{
cipherText.Append(c);
}
}
Console.WriteLine( "Cipher Text is: " + cipherText);
Dictionary< char , char > dict2 = new Dictionary< char , char >();
for ( int i = 0; i < allLetters.Length; i++)
{
dict2.Add(allLetters[i],
allLetters[(i - key + allLetters.Length) % allLetters.Length]);
}
StringBuilder decryptedText = new StringBuilder();
foreach ( char c in cipherText.ToString())
{
if (allLetters.IndexOf(c) != -1)
{
decryptedText.Append(dict2);
}
else
{
decryptedText.Append(c);
}
}
Console.WriteLine( "Recovered plain text: " + decryptedText);
}
}
}
|
Javascript
const all_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
const dict1 = {};
const key = 4;
for (let i = 0; i < all_letters.length; i++) {
dict1[all_letters[i]] = all_letters[(i + key) % all_letters.length];
}
const plain_txt = "I am studying Data Encryption" ;
let cipher_txt = "" ;
for (let i = 0; i < plain_txt.length; i++) {
const char = plain_txt[i];
if (all_letters.includes(char)) {
const temp = dict1[char];
cipher_txt += temp;
} else {
cipher_txt += char;
}
}
console.log( "Cipher Text is: " , cipher_txt);
const dict2 = {};
for (let i = 0; i < all_letters.length; i++) {
dict2[all_letters[i]] = all_letters[(i - key + all_letters.length) % all_letters.length];
}
let decrypt_txt = "" ;
for (let i = 0; i < cipher_txt.length; i++) {
const char = cipher_txt[i];
if (all_letters.includes(char)) {
const temp = dict2[char];
decrypt_txt += temp;
} else {
decrypt_txt += char;
}
}
console.log( "Recovered plain text :" , decrypt_txt);
|
Output
Cipher Text is: M eq wxyhCmrk Hexe IrgvCtxmsr
Recovered plain text : I am studying Data Encryption
Time Complexity: O(n)
Auxiliary Space: O(n)
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
10 Apr, 2023
Like Article
Save Article