-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcipher.c
More file actions
162 lines (131 loc) · 4.27 KB
/
cipher.c
File metadata and controls
162 lines (131 loc) · 4.27 KB
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
/*! \file cipher.c */
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <ncurses.h>
#include "cipher.h"
bool checkKey(char *strng);
char getSubstitution (char scrt_char, char plainOrCipher_char, bool de_Or_en);
/** \brief Check if string contains only letters of the alphabet.
*
* Iterate through each character in a string and return false if a character is not
* a letter from the alphabet.
* @param[in] strng String to check.
* \returns bool True if only letters, false otherwise. */
bool checkKey(char *strng){
int counter = 0;
while (strng[counter] != '\0'){
if (!isalpha(strng[counter])){
printw("Can't be used because it contains %d\n", strng[counter]);
return false;
}
counter++;
}
return true;
}
/** \brief Substitute one character with another.
*
* This function is used for both encryption and decryption by way of a boolean value. Characters are converted to uppercase. For each character it performs the appropriate substitution.
*
* @param[in] scrt_char Secret-Key character.
* @param[in] plainOrCipher_char Character from plaintext or ciphertext.
* @param[in] encryptOrDecrypt Bool indicating whether to encrypt (true) or
* decrypt (false).
* */
char getSubstitution (char scrt_char, char plainOrCipher_char, bool Encrypt){
static const char alphabet[ALPHABET_LENGTH] = {
'A','B','C','D','E',
'F','G','H','I','J',
'K','L','M','N','O',
'P','Q','R','S','T',
'U','V','W','X','Y','Z'};
static char Vigenere_Square[ALPHABET_LENGTH][ALPHABET_LENGTH] = {{' '}};
if ((Vigenere_Square[0][0]) == ' '){ // call first time only
for (size_t i = 0; i < ALPHABET_LENGTH; i++) {
for (size_t j = 0; j < ALPHABET_LENGTH; j++){
Vigenere_Square[i][j] = alphabet[(j + i) % ALPHABET_LENGTH];
}
}
}
// convert to integer to traverse array
// the ascii code for each is
// a = 97, A = 65;
int scrt_char_n;
int plain_char_n;
plainOrCipher_char = toupper(plainOrCipher_char);
scrt_char = toupper(scrt_char);
// give ascii numbers
if (isupper(scrt_char)){scrt_char_n = scrt_char - 65;} // A = 0, ... Z = 25
if (isupper(plainOrCipher_char)) {plain_char_n = plainOrCipher_char - 65;}
// encrypt
if((Encrypt)){
return Vigenere_Square[scrt_char_n][plain_char_n];
}
if(!(Encrypt)){
#ifdef DEBUG
puts("Values supplied to function:");
printf("scrt_char: %c\n", scrt_char);
printf("plainOrCipher_char %c\n", plainOrCipher_char);
puts("");
puts("Converted to:");
printf("scrt_char_n: %d\n", scrt_char_n);
printf("plain_char_n: %d\n", plain_char_n);
#endif
for (size_t i = 0; i < ALPHABET_LENGTH; i++){
if(Vigenere_Square[scrt_char_n][i] == plainOrCipher_char){
return Vigenere_Square[0][i];
}
}
}
}
/** Walks along plaintext string, repeatedly calling getSubstitution.
* @param[in] plainToEncrypt Plain text string.
* @param[in] cipherTextArray Empty string of same length
* @param[in] scrt_strng Secret key string */
int encrypt (char *plainToEncrypt, char *cipherTextArray, char *scrt_strng){
int p_counter = 0, s_counter = 0;
if(!checkKey(scrt_strng)){
return EXIT_FAILURE;
}
while (plainToEncrypt[p_counter] != '\0'){
if (!isalpha(plainToEncrypt[p_counter])){
cipherTextArray[p_counter] = plainToEncrypt[p_counter];
p_counter++;
continue;
}
cipherTextArray[p_counter] = getSubstitution(
scrt_strng[s_counter], plainToEncrypt[p_counter], true);
p_counter++; s_counter++;
if (scrt_strng[s_counter] == '\n'){
s_counter = 0;
}
}
p_counter = 0;
return EXIT_SUCCESS;
}
/** Decrypt ciphertext using a secret key
* @param[in] cipherToDecrypt Ciphertext
* @param[in] plainTextArray Empty string of same length
* @param[in] scrt_strng Secret key string */
int decrypt (char *cipherToDecrypt, char *plainTextArray, char *scrt_strng){
int p_counter = 0, s_counter = 0;
if(!checkKey(scrt_strng)){
return EXIT_FAILURE;
}
while (cipherToDecrypt[p_counter] != '\0'){
if (!isalpha(cipherToDecrypt[p_counter])){
plainTextArray[p_counter] = cipherToDecrypt[p_counter]; // copy.. then move on
p_counter++;
continue;
}
plainTextArray[p_counter] = getSubstitution (
scrt_strng[s_counter], cipherToDecrypt[p_counter], false);
p_counter++; s_counter++;
if (scrt_strng[s_counter] == '\n'){
s_counter = 0;
}
}
p_counter = 0;
return EXIT_SUCCESS;
}