1
1
/* *
2
2
* @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.
4
5
*
5
6
* @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.
8
10
*
9
11
* ### 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
+ *
14
17
* \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,
17
21
*
18
22
* \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
+ *
23
27
* For Example,
24
28
* 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
+ *
31
36
* @author [Deep Raval](https://github.com/imdeep2905)
32
37
*/
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<<
36
42
37
43
/* * \namespace ciphers
38
44
* \brief Algorithms for encryption and decryption
39
45
*/
40
46
namespace 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
107
124
108
125
/* *
109
126
* Function to test above algorithm
@@ -116,15 +133,15 @@ void test() {
116
133
assert (text1 == decrypted1);
117
134
std::cout << " Original text : " << text1;
118
135
std::cout << " , Encrypted text (with key = TESLA) : " << encrypted1;
119
- std::cout << " , Decrypted text : " << decrypted1 << std::endl;
136
+ std::cout << " , Decrypted text : " << decrypted1 << std::endl;
120
137
// Test 2
121
138
std::string text2 = " GOOGLEIT" ;
122
139
std::string encrypted2 = ciphers::vigenere::encrypt (text2, " REALLY" );
123
140
std::string decrypted2 = ciphers::vigenere::decrypt (encrypted2, " REALLY" );
124
141
assert (text2 == decrypted2);
125
142
std::cout << " Original text : " << text2;
126
143
std::cout << " , Encrypted text (with key = REALLY) : " << encrypted2;
127
- std::cout << " , Decrypted text : " << decrypted2 << std::endl;
144
+ std::cout << " , Decrypted text : " << decrypted2 << std::endl;
128
145
}
129
146
130
147
/* * Driver Code */
0 commit comments