commit 39192ec9f64bbb27bc451beab2ded9e1f86e8629 Author: bot50 Date: Sat Feb 24 20:16:06 2024 +0000 kukemuna-cs50/problems/2024/x/caesar@20240224T201606.557524781Z diff --git a/caesar.c b/caesar.c new file mode 100644 index 0000000..fe79c84 --- /dev/null +++ b/caesar.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +int key_to_int_reduced(string s_key); +void rotate(string plaintext, int i_key); + +int main(int argc, string argv[]) +{ + // Print usage and exit if argc is not 2 or key is not integer + if (argc != 2 || key_to_int_reduced(argv[1]) < 0) + { + printf("Usage: ./caesar key\n"); + return 1; + } + else + { + string s_key = argv[1]; + int i_key = key_to_int_reduced(s_key); + string plaintext = get_string("plaintext: "); + rotate(plaintext, i_key); + } + return 0; +} + +// Convert a string of numbers to integer +int key_to_int_reduced(string s_key) +{ + int key = 0; + + // Iterate each string element + for (int i = 0; i < strlen(s_key); i++) + { + if (isdigit(s_key[i])) + { + key += ((int) s_key[i] - 48); + if (i < strlen(s_key) - 1) + { + key *= 10; + } + } + // Cancel if not digit + else + { + return -1; + } + } + + // Reduce key size to < 26 + while (key >= 26) + { + key %= 26; + } + return key; +} + +void rotate(string plaintext, int i_key) +{ + printf("ciphertext: "); + + // Iterate each plaintext element + for (int i = 0; i < strlen(plaintext); i++) + { + // Apply key for text characters only + if (isalpha(plaintext[i])) + { + // Rollover and rotate characters, upper- and lowercase + if ((isupper(plaintext[i]) && plaintext[i] + i_key > 90) || (islower(plaintext[i]) && plaintext[i] + i_key > 122)) + { + printf("%c", plaintext[i] + i_key - 26); + } + // Rotate characters + else + { + printf("%c", plaintext[i] + i_key); + } + } + // Leave non-alphanumerics as-is + else + { + printf("%c", plaintext[i]); + } + } + printf("\n"); +}