forked from HarshCasper/NeoAlgo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Vernam_Cipher.c
274 lines (179 loc) · 5.76 KB
/
Vernam_Cipher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/*In Vernam cipher(also known as the One-Time Pad), the length of the plaintext, ciphertext, and key is the same.
Below is an implementation of Vernam cipher in the C language.*/
/*Basically, here the ith letter of the cipher text is fomred by shifting the ith letter of the plaintext with
* the ith letter of key.
* */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//This defines the maximum length of the string in which we want to perform encrypt and decrypt operations.
#define LENGTH_MAX 100
// This is the decrypt function which takes ciphertext and key as input
char *decrypt(char *ciphertext, char *key) {
static char decrypted[LENGTH_MAX];
for(int i = 0; i < strlen(key); i++) {
//Convert the character to ASCII
int ct = ciphertext[i] - 0;
ct -= 65;
//We number alphabets as A-0, B-1, ..... , Z-25. So,
//We shift the obtained ASCII value by 65.
//We perform similar steps for the key.
int k = key[i] - 0;
k -= 65;
//The plaintext is obtained by shifting the ciphertext backwards by the key
int pt = ct - k;
//If the value goes below 0, we add 26 to it, as number of cycle doesn't matter
//Since, at last we take mod by 26.
while(pt < 0) {
pt += 26;
}
pt = pt % 26;
//We add back 65 to convert it back to ASCII and then to char
pt += 65;
char plaintext = pt;
decrypted[i] = plaintext;
}
//Return the decrypted message
return decrypted;
}
// This is the encrypt function which takes plaintext and key as input
char* encrypt(char *plaintext, char *key) {
static char encrypted[LENGTH_MAX];
for(int i = 0; i < strlen(key); i++) {
//Convert the character to ASCII
int pt = plaintext[i] - 0;
//We number alphabets as A-0, B-1, ..... , Z-25. So,
//We shift the obtained ASCII value by 65.
pt -= 65;
//We perform similar steps for the key.
int k = key[i] - 0;
k -= 65;
//The ciphertext is obtained by shifting the ciphertext backwards by the key
int cipher = pt + k;
cipher = cipher % 26;
//We add back 65 to convert it back to ASCII and then to char
cipher += 65;
char enc = cipher;
encrypted[i] = enc;
}
//Return the decrypted message
return encrypted;
}
int main() {
//while true
while(1) {
//Ask user for input on what he wants to perform
printf("\nVERNAM CIPHER\n");
printf("\n1. Encrypt a plaintext\n");
printf("2. Decrypt a ciphertext\n");
printf("3. Exit\n\n");
printf("Enter your choice - ");
int choice;
//Take choice of user
scanf("%d", &choice);
//If user has chosen to exit
if(choice == 3)
exit(0);
//If the user has chosen to encrypt
else if(choice == 1) {
char message[LENGTH_MAX];
printf("Enter the plaintext you want to encrypt - ");
//Take the plaintext message as input from the user
scanf("%s", message);
int len_plaintext = strlen(message);
// Converts all characters to upper case to maintain unity
for (int i = 0; message[i] != '\0'; i++) {
if(message[i] >= 'a' && message[i] <= 'z') {
message[i] -= 32;
}
}
char key[LENGTH_MAX];
printf("Enter the key of the same size as the plaintext - ");
scanf("%s", key);
int len_key = strlen(key);
// Checks if the length of the key is equal to that of plaintext or not
// If not then prompts user for entering another key
while(len_key != len_plaintext) {
printf("\nPlease enter a key whose length is same as that of the plaintext.\n");
printf("Key - ");
scanf("%s", key);
len_key = strlen(key);
}
// Converts all characters to upper case to maintain unity
for(int i = 0; key[i] != '\0'; i++) {
if(key[i] >= 'a' && key[i] <= 'z') {
key[i] -= 32;
}
}
//Print the encrypted text
printf("\nThe encrypted text is %s\n", encrypt(&message[0], &key[0]));
}
//If the user has chosen to decrypt
else if(choice == 2) {
char ciphertext[LENGTH_MAX];
printf("Enter the ciphertext you want to decrypt - ");
//Take ciphertext as input from user
scanf("%s", ciphertext);
int len_ciphertext = strlen(ciphertext);
// Converts all characters to upper case to maintain unity
for (int i = 0; ciphertext[i] != '\0'; i++) {
if(ciphertext[i] >= 'a' && ciphertext[i] <= 'z') {
ciphertext[i] -= 32;
}
}
char key[LENGTH_MAX];
printf("Enter the key of the same size as the ciphertext - ");
scanf("%s", key);
int len_key = strlen(key);
// Checks if the length of the key is equal to that of ciphertext or not
// If not then prompts user for entering another key
while(len_key != len_ciphertext) {
printf("\nPlease enter a key whose length is same as that of the ciphertext.\n");
printf("Key - ");
scanf("%s", key);
len_key = strlen(key);
}
// Converts all characters to upper case to maintain unity
for(int i = 0; key[i] != '\0'; i++) {
if(key[i] >= 'a' && key[i] <= 'z') {
key[i] -= 32;
}
}
printf("\nThe decrypted text is %s\n", decrypt(&ciphertext[0], &key[0]));
}
else {
printf("\nPlease enter a valid choice.\n");
}
}
return 0;
}
/*Test Case -
VERNAM CIPHER
1. Encrypt a plaintext
2. Decrypt a ciphertext
3. Exit
Enter your choice - 1
Enter the plaintext you want to encrypt - thisisatestcase
Enter the key of the same size as the plaintext - thisisthereqkey
The encrypted text is MOQKQKTAIJXSKWC
VERNAM CIPHER
1. Encrypt a plaintext
2. Decrypt a ciphertext
3. Exit
Enter your choice - 2
Enter the ciphertext you want to decrypt - moqkqktaijxskwc
Enter the key of the same size as the ciphertext - thisisthereqkey
The decrypted text is THISISATESTCASE
VERNAM CIPHER
1. Encrypt a plaintext
2. Decrypt a ciphertext
3. Exit
Enter your choice - 4
Please enter a valid choice.
VERNAM CIPHER
1. Encrypt a plaintext
2. Decrypt a ciphertext
3. Exit
Enter your choice - 3
*
* */