11/* *
22 * @file vigenere_cipher.cpp
3- * @brief Implementation of [Vigenère cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
3+ * @brief Implementation of [Vigenère
4+ * cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
45 *
56 * @details
6- * The Vigenère cipher is a method of encrypting alphabetic text by using a series of interwoven vigenere
7- * ciphers, based on the letters of a keyword. It employs a form of polyalphabetic substitution.
7+ * The Vigenère cipher is a method of encrypting alphabetic text by using a
8+ * series of interwoven vigenere ciphers, based on the letters of a keyword. It
9+ * employs a form of polyalphabetic substitution.
810 *
911 * ### Algorithm
10- * The encryption can also be represented using modular arithmetic by first transforming
11- * the letters into numbers, according to the scheme, A → 0, B → 1, ..., Z → 25.
12- * Encryption of \f$i^{th}\f$ character in Message M by key K can be described mathematically as,
13- *
12+ * The encryption can also be represented using modular arithmetic by first
13+ * transforming the letters into numbers, according to the scheme, A → 0, B → 1,
14+ * ..., Z → 25. Encryption of \f$i^{th}\f$ character in Message M by key K can
15+ * be described mathematically as,
16+ *
1417 * \f[ E_{K}(M_{i}) = (M_{i} + K_{i})\;\mbox{mod}\; 26\f]
15- *
16- * while decryption of \f$i^{th}\f$ character in Cipher C by key K can be described mathematically as,
18+ *
19+ * while decryption of \f$i^{th}\f$ character in Cipher C by key K can be
20+ * described mathematically as,
1721 *
1822 * \f[ D_{k}(C_{i}) = (C_{i} - K_{i} + 26)\;\mbox{mod}\; 26\f]
19- *
20- * Where \f$K_{i}\f$ denotes corresponding character in key. If \f$|key| < |text|\f$ than
21- * same key is repeated untill their lengths are equal.
22- *
23+ *
24+ * Where \f$K_{i}\f$ denotes corresponding character in key. If \f$|key| <
25+ * |text|\f$ than same key is repeated untill their lengths are equal.
26+ *
2327 * For Example,
2428 * If M = "ATTACKATDAWN" and K = "LEMON" than K becomes "LEMONLEMONLE".
25- *
26- * \note Rather than creating new key of equal length this program does this by using modular index for key
27- * (i.e. \f$(j + 1) \;\mbox{mod}\; |\mbox{key}|\f$)
28- *
29- * \note This program implements Vigenère cipher for only uppercase English alphabet characters (i.e. A-Z).
30- *
29+ *
30+ * \note Rather than creating new key of equal length this program does this by
31+ * using modular index for key (i.e. \f$(j + 1) \;\mbox{mod}\; |\mbox{key}|\f$)
32+ *
33+ * \note This program implements Vigenère cipher for only uppercase English
34+ * alphabet characters (i.e. A-Z).
35+ *
3136 * @author [Deep Raval](https://github.com/imdeep2905)
3237 */
33- #include < iostream>
34- #include < string>
35- #include < cassert>
38+ #include < cassert> // for assert
39+ #include < cstddef> // for size_t
40+ #include < iostream> // for basic_ostream, operator<<, cout, endl
41+ #include < string> // for basic_string, char_traits, string, operator<<
3642
3743/* * \namespace ciphers
3844 * \brief Algorithms for encryption and decryption
3945 */
4046namespace ciphers {
41- /* * \namespace vigenere
42- * \brief Functions for [vigenère cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
43- */
44- namespace vigenere {
45- namespace {
46- /* *
47- * This function finds character for given value (i.e.A-Z)
48- * @param x value for which we want character
49- * @return corresponding character for perticular value
50- */
51- inline char get_char (const int x) {
52- // By adding 65 we are scaling 0-25 to 65-90.
53- // Which are in fact ASCII values of A-Z.
54- return char (x + 65 );
55- }
56- /* *
57- * This function finds value for given character (i.e.0-25)
58- * @param c character for which we want value
59- * @return returns corresponding value for perticular character
60- */
61- inline int get_value (const char c) {
62- // A-Z have ASCII values in range 65-90.
63- // Hence subtracting 65 will scale them to 0-25.
64- return int (c - 65 );
65- }
66- } // Unnamed namespace
67- /* *
68- * Encrypt given text using vigenere cipher.
69- * @param text text to be encrypted
70- * @param key to be used for encryption
71- * @return new encrypted text
72- */
73- std::string encrypt (const std::string &text, const std::string &key) {
74- std::string encrypted_text = " " ; // Empty string to store encrypted text
75- // Going through each character of text and key
76- // Note that key is visited in circular way hence j = (j + 1) % |key|
77- for (size_t i = 0 , j = 0 ; i < text.length (); i++, j = (j + 1 ) % key.length ()) {
78- int place_value_text = get_value (text[i]); // Getting value of character in text
79- int place_value_key = get_value (key[j]); // Getting value of character in key
80- place_value_text = (place_value_text + place_value_key) % 26 ; // Applying encryption
81- char encrypted_char = get_char (place_value_text); // Getting new character from encrypted value
82- encrypted_text += encrypted_char; // Appending encrypted character
83- }
84- return encrypted_text; // Returning encrypted text
85- }
86- /* *
87- * Decrypt given text using vigenere cipher.
88- * @param text text to be decrypted
89- * @param key key to be used for decryption
90- * @return new decrypted text
91- */
92- std::string decrypt (const std::string &text, const std::string &key) {
93- // Going through each character of text and key
94- // Note that key is visited in circular way hence j = (j + 1) % |key|
95- std::string decrypted_text = " " ; // Empty string to store decrypted text
96- for (size_t i = 0 , j = 0 ; i < text.length (); i++, j = (j + 1 ) % key.length ()) {
97- int place_value_text = get_value (text[i]); // Getting value of character in text
98- int place_value_key = get_value (key[j]); // Getting value of character in key
99- place_value_text = (place_value_text - place_value_key + 26 ) % 26 ; // Applying decryption
100- char decrypted_char = get_char (place_value_text); // Getting new character from decrypted value
101- decrypted_text += decrypted_char; // Appending decrypted character
102- }
103- return decrypted_text; // Returning decrypted text
104- }
105- } // namespace vigenere
106- } // namespace ciphers
47+ /* * \namespace vigenere
48+ * \brief Functions for [vigenère
49+ * cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
50+ */
51+ namespace vigenere {
52+ namespace {
53+ /* *
54+ * This function finds character for given value (i.e.A-Z)
55+ * @param x value for which we want character
56+ * @return corresponding character for perticular value
57+ */
58+ inline char get_char (const int x) {
59+ // By adding 65 we are scaling 0-25 to 65-90.
60+ // Which are in fact ASCII values of A-Z.
61+ return char (x + 65 );
62+ }
63+ /* *
64+ * This function finds value for given character (i.e.0-25)
65+ * @param c character for which we want value
66+ * @return returns corresponding value for perticular character
67+ */
68+ inline int get_value (const char c) {
69+ // A-Z have ASCII values in range 65-90.
70+ // Hence subtracting 65 will scale them to 0-25.
71+ return int (c - 65 );
72+ }
73+ } // Unnamed namespace
74+ /* *
75+ * Encrypt given text using vigenere cipher.
76+ * @param text text to be encrypted
77+ * @param key to be used for encryption
78+ * @return new encrypted text
79+ */
80+ std::string encrypt (const std::string &text, const std::string &key) {
81+ std::string encrypted_text = " " ; // Empty string to store encrypted text
82+ // Going through each character of text and key
83+ // Note that key is visited in circular way hence j = (j + 1) % |key|
84+ for (size_t i = 0 , j = 0 ; i < text.length ();
85+ i++, j = (j + 1 ) % key.length ()) {
86+ int place_value_text =
87+ get_value (text[i]); // Getting value of character in text
88+ int place_value_key =
89+ get_value (key[j]); // Getting value of character in key
90+ place_value_text =
91+ (place_value_text + place_value_key) % 26 ; // Applying encryption
92+ char encrypted_char = get_char (
93+ place_value_text); // Getting new character from encrypted value
94+ encrypted_text += encrypted_char; // Appending encrypted character
95+ }
96+ return encrypted_text; // Returning encrypted text
97+ }
98+ /* *
99+ * Decrypt given text using vigenere cipher.
100+ * @param text text to be decrypted
101+ * @param key key to be used for decryption
102+ * @return new decrypted text
103+ */
104+ std::string decrypt (const std::string &text, const std::string &key) {
105+ // Going through each character of text and key
106+ // Note that key is visited in circular way hence j = (j + 1) % |key|
107+ std::string decrypted_text = " " ; // Empty string to store decrypted text
108+ for (size_t i = 0 , j = 0 ; i < text.length ();
109+ i++, j = (j + 1 ) % key.length ()) {
110+ int place_value_text =
111+ get_value (text[i]); // Getting value of character in text
112+ int place_value_key =
113+ get_value (key[j]); // Getting value of character in key
114+ place_value_text = (place_value_text - place_value_key + 26 ) %
115+ 26 ; // Applying decryption
116+ char decrypted_char = get_char (
117+ place_value_text); // Getting new character from decrypted value
118+ decrypted_text += decrypted_char; // Appending decrypted character
119+ }
120+ return decrypted_text; // Returning decrypted text
121+ }
122+ } // namespace vigenere
123+ } // namespace ciphers
107124
108125/* *
109126 * Function to test above algorithm
@@ -116,15 +133,15 @@ void test() {
116133 assert (text1 == decrypted1);
117134 std::cout << " Original text : " << text1;
118135 std::cout << " , Encrypted text (with key = TESLA) : " << encrypted1;
119- std::cout << " , Decrypted text : " << decrypted1 << std::endl;
136+ std::cout << " , Decrypted text : " << decrypted1 << std::endl;
120137 // Test 2
121138 std::string text2 = " GOOGLEIT" ;
122139 std::string encrypted2 = ciphers::vigenere::encrypt (text2, " REALLY" );
123140 std::string decrypted2 = ciphers::vigenere::decrypt (encrypted2, " REALLY" );
124141 assert (text2 == decrypted2);
125142 std::cout << " Original text : " << text2;
126143 std::cout << " , Encrypted text (with key = REALLY) : " << encrypted2;
127- std::cout << " , Decrypted text : " << decrypted2 << std::endl;
144+ std::cout << " , Decrypted text : " << decrypted2 << std::endl;
128145}
129146
130147/* * Driver Code */
0 commit comments