feat: add Caesar Cipher (#957)

* Added caesar_cipher.cpp

* Added ranged based loops and made some args pass by ref

* Changed comment styling and added unnamed namespace

* Update ciphers/caesar_cipher.cpp

Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>

Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com>
This commit is contained in:
Deep Raval 2020-07-20 00:20:02 +05:30 committed by GitHub
parent ef1bf8849e
commit 01581bfd5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

124
ciphers/caesar_cipher.cpp Normal file
View File

@ -0,0 +1,124 @@
/**
* @file caesar_cipher.cpp
* @brief Implementation of [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher) algorithm.
*
* @details
* In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher,
* Caesar's code or Caesar shift, is one of the simplest and most widely known encryption
* techniques. It is a type of substitution cipher in which each letter in the plaintext
* is replaced by a letter some fixed number of positions down the alphabet. For example,
* with a left shift of 3, D would be replaced by A, E would become B, and so on.
* The method is named after Julius Caesar, who used it in his private correspondence.
*
* ### Algorithm
* The encryption can also 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 x by a shift n can be described mathematically as,
* \f[ E(x) = (x + n)\;\mbox{mod}\; 26\f]
* while decryption can be described as,
* \f[ D(x) = (x - n) \;\mbox{mod}\; 26\f]
*
* \note This program implements caesar cipher for only uppercase English alphabet characters (i.e. A-Z).
*
* @author [Deep Raval](https://github.com/imdeep2905)
*/
#include <iostream>
#include <string>
#include <cassert>
/** \namespace ciphers
* \brief Algorithms for encryption and decryption
*/
namespace ciphers {
/** \namespace caesar
* \brief Functions for [Caesar cipher](https://en.wikipedia.org/wiki/Caesar_cipher) algorithm.
*/
namespace caesar {
namespace {
/**
* This function finds character for given value (i.e.A-Z)
* @param x value for which we want character
* @returns corresponding character for perticular value
*/
inline char get_char(const int x) {
// By adding 65 we are scaling 0-25 to 65-90.
// Which are in fact ASCII values of A-Z.
return char(x + 65);
}
/**
* This function finds value for given character (i.e.0-25)
* @param c character for which we want value
* @returns returns corresponding value for perticular character
*/
inline int get_value(const char c) {
// A-Z have ASCII values in range 65-90.
// Hence subtracting 65 will scale them to 0-25.
return int(c - 65);
}
} // Unnamed namespace
/**
* Encrypt given text using caesar cipher.
* @param text text to be encrypted
* @param shift number of shifts to be applied
* @returns new encrypted text
*/
std::string encrypt (const std::string &text, const int &shift) {
std::string encrypted_text = ""; // Empty string to store encrypted text
for (char c : text) { // Going through each character
int place_value = get_value(c); // Getting value of character (i.e. 0-25)
place_value = (place_value + shift) % 26; // Applying encryption formula
char new_char = get_char(place_value); // Getting new character from new value (i.e. A-Z)
encrypted_text += new_char; // Appending encrypted character
}
return encrypted_text; // Returning encrypted text
}
/**
* Decrypt given text using caesar cipher.
* @param text text to be decrypted
* @param shift number of shifts to be applied
* @returns new decrypted text
*/
std::string decrypt (const std::string &text, const int &shift) {
std::string decrypted_text = ""; // Empty string to store decrypted text
for (char c : text) { // Going through each character
int place_value = get_value(c); // Getting value of character (i.e. 0-25)
place_value = (place_value - shift) % 26;// Applying decryption formula
if(place_value < 0) { // Handling case where remainder is negative
place_value = place_value + 26;
}
char new_char = get_char(place_value); // Getting original character from decrypted value (i.e. A-Z)
decrypted_text += new_char; // Appending decrypted character
}
return decrypted_text; // Returning decrypted text
}
} // namespace caesar
} // namespace ciphers
/**
* Function to test above algorithm
*/
void test() {
// Test 1
std::string text1 = "ALANTURING";
std::string encrypted1 = ciphers::caesar::encrypt(text1, 17);
std::string decrypted1 = ciphers::caesar::decrypt(encrypted1, 17);
assert(text1 == decrypted1);
std::cout << "Original text : " << text1;
std::cout << " , Encrypted text (with shift = 21) : " << encrypted1;
std::cout << " , Decrypted text : "<< decrypted1 << std::endl;
// Test 2
std::string text2 = "HELLOWORLD";
std::string encrypted2 = ciphers::caesar::encrypt(text2, 1729);
std::string decrypted2 = ciphers::caesar::decrypt(encrypted2, 1729);
assert(text2 == decrypted2);
std::cout << "Original text : " << text2;
std::cout << " , Encrypted text (with shift = 1729) : " << encrypted2;
std::cout << " , Decrypted text : "<< decrypted2 << std::endl;
}
/** Driver Code */
int main() {
// Testing
test();
return 0;
}