/* ** $Id: caesar.c 759 2008-02-13 14:27:49Z phf $ ** ** Simple Caesar Cipher for Week 3 Lab. ** ** Hacked by Rebecca Shapiro and ** Peter H. Froehlich . */ #include #include #include #include #include /* range for keys, since there are 26 letters */ #define MIN_KEY 0 #define MAX_KEY 25 #define MOD_KEY (MAX_KEY+1) /* are we encrypting or decrypting? */ static bool encrypt = true; /* key from the command line */ static int key = -1; /* print usage information and fail */ static void usage(void) { printf("usage: caesar (en|de) key {key}\n"); exit(EXIT_FAILURE); } /* handle all arguments and set globals accordingly */ static void handle_arguments(int argc, char *argv[]) { /* check basic command line format */ if (argc < 3) { usage(); } else if (argc > 3) { printf("caesar: multiple keys (Vigenere) not implemented, ignored\n"); } /* check whether we encrypt or decrypt */ if (strcmp(argv[1], "en") == 0) { encrypt = true; } else if (strcmp(argv[1], "de") == 0) { encrypt = false; } else { usage(); } /* check that key is valid and extract it */ if (!isdigit(argv[2][0])) { // not quite right for -1 but what the heck... :-) printf("caeser: key %s is not an integer\n", argv[2]); exit(EXIT_FAILURE); } /* TODO: we should use strtol for error checking here! */ key = (int) strtol(argv[2], NULL, 10); /* check that range for key is valid */ if (!(MIN_KEY <= key && key <= MAX_KEY)) { printf("caeser: key %s is out of range\n", argv[2]); exit(EXIT_FAILURE); } } /* return encrypted (or decrypted) char for given char */ static char crypt(char c) { /* we only deal with lower case */ c = tolower(c); /* we only encrypt letters */ if ('a' <= c && c <= 'z') { if (encrypt) { c = (((c - 'a') + (char)key) % MOD_KEY) + 'a'; } else { // we add an extra 26 to the key so we don't have any negative // numbers, because C treats -1 % 26 as equaling -1, and not 25 c = ((((c - 'a') - (char)key) + (char)MOD_KEY) % MOD_KEY) + 'a'; } } return c; } /* main program processing input/output */ int main (int argc, char * argv[]) { int c; // deal with arguments handle_arguments(argc, argv); // encrypt/decrypt from standard in to standard out while ((c = getchar()) != EOF) { printf("%c", crypt((char)c)); } // and done... :-) return EXIT_SUCCESS; }