1
1
/* *
2
2
* @file vigenere_cipher.cpp
3
- * @brief Implementation of [Vigenère
4
- * cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
3
+ * @brief Implementation of [Vigenère cipher](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) algorithm.
5
4
*
6
5
* @details
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.
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.
10
8
*
11
9
* ### Algorithm
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
- *
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
+ *
17
14
* \f[ E_{K}(M_{i}) = (M_{i} + K_{i})\;\mbox{mod}\; 26\f]
18
- *
19
- * while decryption of \f$i^{th}\f$ character in Cipher C by key K can be
20
- * described mathematically as,
15
+ *
16
+ * while decryption of \f$i^{th}\f$ character in Cipher C by key K can be described mathematically as,
21
17
*
22
18
* \f[ D_{k}(C_{i}) = (C_{i} - K_{i} + 26)\;\mbox{mod}\; 26\f]
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
- *
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
+ *
27
23
* For Example,
28
24
* If M = "ATTACKATDAWN" and K = "LEMON" than K becomes "LEMONLEMONLE".
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
- *
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
+ *
36
31
* @author [Deep Raval](https://github.com/imdeep2905)
37
32
*/
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<<
33
+ #include < iostream>
34
+ #include < string>
35
+ #include < cassert>
42
36
43
37
/* * \namespace ciphers
44
38
* \brief Algorithms for encryption and decryption
45
39
*/
46
40
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
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
124
107
125
108
/* *
126
109
* Function to test above algorithm
@@ -133,15 +116,15 @@ void test() {
133
116
assert (text1 == decrypted1);
134
117
std::cout << " Original text : " << text1;
135
118
std::cout << " , Encrypted text (with key = TESLA) : " << encrypted1;
136
- std::cout << " , Decrypted text : " << decrypted1 << std::endl;
119
+ std::cout << " , Decrypted text : " << decrypted1 << std::endl;
137
120
// Test 2
138
121
std::string text2 = " GOOGLEIT" ;
139
122
std::string encrypted2 = ciphers::vigenere::encrypt (text2, " REALLY" );
140
123
std::string decrypted2 = ciphers::vigenere::decrypt (encrypted2, " REALLY" );
141
124
assert (text2 == decrypted2);
142
125
std::cout << " Original text : " << text2;
143
126
std::cout << " , Encrypted text (with key = REALLY) : " << encrypted2;
144
- std::cout << " , Decrypted text : " << decrypted2 << std::endl;
127
+ std::cout << " , Decrypted text : " << decrypted2 << std::endl;
145
128
}
146
129
147
130
/* * Driver Code */
0 commit comments