COMP2113
COMP2113_ENGG1340 Programming technologies and Computer programming II [Section 2BC] [2023]
Loading...
Searching...
No Matches
1.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <string>
3#include <cmath>
4using namespace std;
5
6char encryption(int key1, int key2, char letter);
7char decryption(int key1, int key2, char letter);
8bool check_within_a_z(char test);
9void convert_position_alphabet(char &letter);
10int find_mmi(int a, int mod_value);
11// gcd() is redundant, since given the assumption:
12// "Input key a will always be a valid key such that decryption is possible."
13// invalid key will gcd(a, 26) > 1, hence not having
14// modular multiplicative inverse, hence not able to decrypt
15// details are mentioned in the decryption() function below.
16int gcd(int a, int b);
17
18
19int main(){
20 char mode;
21 int key1, key2;
22 string input;
23 cin >> mode >> key1 >> key2;
24 char character;
25 while(true){
26 cin >> character;
27 input.push_back(character);
28 if (character == '!'){
29 break;
30 }
31 else{
32 input.push_back(' ');
33 }
34 }
35 switch(mode){
36 case 'e':
37 for (int i=0; i < input.length(); i++){
38 if (check_within_a_z(input[i])){
39 cout << encryption(key1, key2, input[i]);
40 }
41 else{
42 cout << input[i];
43 }
44 }
45 cout << endl;
46 break;
47 case 'd':
48 for (int i=0; i < input.length(); i++){
49 if (check_within_a_z(input[i])){
50 cout << decryption(key1, key2, input[i]);
51 }
52 else{
53 cout << input[i];
54 }
55 }
56 cout << endl;
57 break;
58 }
59 return 0;
60}
61
62char encryption(int key1, int key2, char letter){
63 bool upper_case = isupper(letter);
65 // y = (ax+b) mod 26
66 letter = abs((letter*key1+key2) % 26);
67 if (upper_case){
68 // change to lowercase
69 letter = letter + 97;
70 }
71 else{
72 // original was lowercase, change to upper
73 letter = letter + 65;
74 }
75 return letter;
76}
77
78char decryption(int key1, int key2, char letter){
79 bool upper_case = isupper(letter);
80 // Assumption:
81 // Input key a will always be a valid key such that decryption is possible.
82 // Meaning that if gcd(key1, 26) != 1, then we are fked :()
83 // for example, "e 4 25 w !" gives "J !",
84 // but "d 4 25 J !" gives "j !"
85 // since 4 and 26 are not coprime, there is no modular multiplicative inverse
86 // for 4, so we cannot decrypt the message.
87 // TLDR: The code should NEVER reach the else part
88 // If it reaches, it means the key1 and 26 are not coprime
89 // Indicating INVALID KEY
90 if (gcd(key1, 26) == 1){
91
93 int mmi_of_a = find_mmi(key1,26);
94 int y = mmi_of_a*(letter-key2) % 26;
95 if (y < 0){
96 y += 26;
97 }
98 letter = y;
99 if (upper_case){
100 letter = letter + 97;
101 }
102 else{
103 letter = letter + 65;
104 }
105 return letter;
106 }
107 else{
108 // NOTE: If we ever reached here, then it means that the key is invalid
109 // The program should not reach here in the first place
110 // If you want to try out the brute force method, you can
111 // Change the condition if (gcd(key1, 26) == 1) to if (false)
112 // brute force method
113 return '!'; // comment this line if you want to try out the brute force method
114 int change_case = upper_case ? 32 : 0;
115 for (int i = 65+change_case; i < 91+change_case; i++){
116 if (encryption(key1, key2, (char)i) == letter){
117 return i;
118 }
119 }
120 }
121 return letter;
122}
123
124int find_mmi(int a, int mod_value){
125 // find the modular multiplicative inverse a^-1 by brute force
126 // such that a*a^-1 = 1 (mod mod_value)
127 // todo: proof this is correct
128 for (int i = 1; i <= mod_value; i++){
129 if (abs(a*i % mod_value) == 1){
130 return i;
131 }
132 }
133 return -1; // indicate no mmi exists
134 // which indicate a and mod_value are not coprime
135 // in this program, it means that the key is invalid
136 // Note: This function should never return -1 as you should check their gcd() first
137 // before using find_mmi();
138}
139
140void convert_position_alphabet(char &letter){
141 if ((int)letter >= 97){
142 // convert to upper case
143 letter = ((int)letter - 32);
144 }
145 letter = (int)letter - 65;
146}
147
148bool check_within_a_z(char test){
149 if (((int)test >= 65) && ((int)test <= 90) || ((int)test >= 97) && ((int)test <= 122)){
150 return true;
151 }
152 else{
153 return false;
154 }
155}
156
157int gcd(int a, int b){
158 while(a != b){
159 if (a>b){
160 a -= b;
161 }
162 else if (a<b){
163 b -= a;
164 }
165 else{
166 break;
167 }
168 }
169 return a;
170}
char encryption(int key1, int key2, char letter)
Definition 1.cpp:62
char decryption(int key1, int key2, char letter)
Definition 1.cpp:78
void convert_position_alphabet(char &letter)
Definition 1.cpp:140
bool check_within_a_z(char test)
Definition 1.cpp:148
int find_mmi(int a, int mod_value)
Definition 1.cpp:124
int main()
Definition 1.cpp:19
int gcd(int a, int b)
Definition 1.cpp:157
string upper_case(string str)