-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcaesar.c
134 lines (121 loc) · 3.63 KB
/
caesar.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
// Includes
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdbool.h>
// Delcare functions
bool text(char *s);
void cipher(char *plaintext, char *ciphertext, int k);
char *get_string(const char *prompt);
// argv[1] is the secret key (i.e., a non-negative integer)
int main(int argc, char *argv[])
{
// No user input or multiple inputs error handling
// Text input error handling
if (argc != 2 || text(argv[1]) == true)
{
printf("Usage: %s key\n", argv[0]);
return 1;
}
// Finally run program
else
{
// Capture secret key
int k = atoi(argv[1]);
// Prompt user for text input
char *plaintext = get_string("plaintext: ");
// Get number of characters
int n = strlen(plaintext);
// Make sure to capture terminating null character
char ciphertext[n + 1];
// Call cipher function
cipher(plaintext, ciphertext, k);
// Print ciphertext
printf("ciphertext: %s\n", ciphertext);
// Program exit
return 0;
}
}
// Function to determine if user inputted text
bool text(char *s)
{
// Use a loop to iterate over argv
for (int i = 0; i < strlen(s); i++)
{
char c = s[i];
// If any of the inputted text is non-numerical, return false
if (isdigit(c))
{
return false;
}
}
return true;
}
// Main function: encrpyting the plaintext
void cipher(char *plaintext, char *ciphertext, int k)
{
// Declare i
int i = 0;
// Iterate over each character of the plaintext using for loop:
for (i = 0; i < strlen(plaintext); i++)
{
char ch = plaintext[i];
// Change characters using formula. Change all to lowercase and then convert back to uppercase
if (isalpha(ch))
{
char lower = tolower(ch);
int pi = lower - 'a';
// ci returns number, therefore must anchor the number to letter
char ci = ((pi + k) % 26) + 'a';
// Change character using ci value. If lowercase, keep it as is
if (islower(ch))
{
ciphertext[i] = ci;
}
// Change character using ci value. If uppercase, change to uppercase
else
{
ciphertext[i] = toupper(ci);
}
}
// Non-alphabetical characters should be outputted unchanged
else
{
ciphertext[i] = ch;
}
}
// Lastly, add terminating null character
ciphertext[i] = '\0';
}
// get_string function. Source: https://stackoverflow.com/questions/48282630/troubles-creating-a-get-string-function-in-c
char *get_string(const char *prompt)
{
char temp[26] = "";//24 + newline + '\0'
int size,count;
while ( 1)
{
printf ( "%s",prompt);
if ( fgets ( temp, sizeof temp, stdin)) {
if ( !strchr ( temp, '\n')) {//no newline
printf("\x1B[31mError\x1B[0m: too long.\n%s",prompt);
size = strlen ( temp);
do {
fgets ( temp, sizeof temp, stdin);//read more and discard
size += strlen ( temp);
} while (!strchr ( temp, '\n'));//loop until newline found
printf("size :%i\n",size);
continue;//re prompt
}
break;
}
else {
fprintf ( stderr, "fgets problem\n");
return NULL;
}
}
temp[strcspn ( temp,"\n")] = '\0';//remove newline
char *word = malloc(strlen ( temp) + 1);
strcpy ( word, temp);
return word;
}