#include /* This program enciphers files using one of Vigenere, Beauford or Varian Beauford ciphers. Note inverses means this code also decrypts - eg encipherment by Vigenere can be deciphered by enciphering with Variant Beauford with the same key. Similarly, Beauford is its own inverse. Author: Dr Leisa Condie. December 1992. phoenix@neumann.une.edu.au Dept of Mathematics, Statistics and Computing Science, University of New England - Armidale, New South Wales, 2351, AUSTRALIA. */ #define ALPHA 26 /* length of alphabet for modulo */ #define MAXKEYLENGTH 10 /* maximum length of the key used */ #define BLOCKLENGTH 5 /* for output, how many chars in a block */ #define LINELENGTH 80 /* maximum output characters per line */ char key[MAXKEYLENGTH+1]; /* encipherment key: +1 for possible newline */ int blockcount = 0; /* counts of chars in printed block */ int linechars = 0; /* count of chars printed on current line */ int keylength = 0; /* holds actual length of the key */ int vigenere=0,beauford=0,varbeau=0; /* cipher type is set to 1 (TRUE) if chosen */ FILE *fp; /* set to stdin if interactive, else file */ void getsetup(void) { char ch; /* generic character variable */ char *tmp = key; /* pointer to key array */ /* find cipher type */ ch = getc(fp); if (ch == 'V' || ch == 'v') vigenere = 1; else if (ch == 'B' || ch == 'b') beauford = 1; else if (ch == 'A' || ch == 'a') varbeau = 1; else { /* otherwise error, so notify by stderr and use Vigenere */ fprintf(stderr,"V/B/A ciphers only - Vigenere assumed\n"); vigenere = 1; } while ((ch = getc(fp)) != '\n'); /* if extraneous input, clear it! */ /* get key - anything after the MAXKEYLENGTH'th char is discarded */ for (keylength=0; keylength < MAXKEYLENGTH; keylength++) if ((key[keylength]= getc(fp)) == '\n') break; if (key[keylength] != '\n') { while ((ch = getc(fp)) != '\n'); /* if excess key, clear it! */ fprintf(stderr,"Key truncated to %d characters\n", keylength); } } int encipher(int i) { /* Takes argument i - where we are in the key, Returns tmp - the ciphertext equivalent of the input if the input was alphabetic, else the input character unchanged */ char ch; /* character read in */ int tmp; /* for cipher char calculation */ ch = getc(fp); if (ch >= 'A' && ch <= 'Z') { /* convert to lowercase */ ch = ch - 'A' + 'a'; /* don't trust tolower() */ } if (ch >= 'a' && ch <= 'z') { /* encipher */ if (vigenere) tmp = (ch + key[i] - 2*'a') % ALPHA; else if (beauford) tmp = (key[i] - ch) % ALPHA; else tmp = (ch - key[i]) % ALPHA; /* make offset positive and convert to lowercase char */ while (tmp < 0) tmp += ALPHA; tmp += 'a'; } else tmp = ch; /* else return character unchanged */ return(tmp); } void outputcipher(void) { int cipherch, i=0; /* cipher character */ while (!feof(fp)) { /* keep going whilst there is input */ cipherch = encipher(i); /* generate cipher character */ if (cipherch < 'a' || cipherch > 'z') /* invalid char in */ continue; /* ignore code below - restart loop */ /* check we haven't finished key and need to restart it */ if (i == keylength-1) i=0; else i++; /* if a BLOCKLENGTH block is finished print a space */ if (blockcount == BLOCKLENGTH) { /* check whether a newline is needed yet */ if (linechars > LINELENGTH - BLOCKLENGTH) { putchar('\n'); linechars = 0; } else { putchar(' '); linechars++; } blockcount = 0; } /* print enciphered character */ putchar(cipherch); blockcount++; linechars++; } putchar('\n'); } /* This version of main is set for input to come from the keyboard either directly or through file redirection: e.g. program < input_file */ /* void main(void) { fp = stdin; getsetup(); outputcipher(); } */ /* This version of main looks for an input file whose name is specified on the argument line: e.g. program input_file */ void main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: program \n"); exit(1); } if ((fp = fopen(argv[1],"r")) == NULL) { fprintf(stderr, "File %s cannot be read from\n", argv[1]); exit(1); } getsetup(); outputcipher(); } .