|
|
1.1 ! root 1: /* ! 2: * program to to decrypt caesar(tm) cypher ! 3: * (caesar is a trademark of the roman empire) ! 4: * ! 5: * to compile: ! 6: * ! 7: * cc decrypt.c -lm -o decrypt.c ! 8: * ! 9: * usage: ! 10: * ! 11: * decrypt [n] < file ! 12: * ! 13: * where n is an optional forced rotation. ! 14: * ! 15: * authors: Stan King, John Eldridge, based on algorithm suggested by ! 16: * Bob Morris ! 17: * 29-Sep-82 ! 18: * ! 19: */ ! 20: ! 21: #ifdef SCCSID ! 22: static char *SccsId = "@(#)caesar.c 1.7 4/16/85"; ! 23: #endif /* SCCSID */ ! 24: ! 25: #include <stdio.h> ! 26: #include <ctype.h> ! 27: #include <math.h> ! 28: extern char *calloc(); ! 29: ! 30: main(argc, argv) ! 31: int argc; ! 32: char *argv[]; ! 33: { ! 34: /* letter frequencies (taken from some unix(tm) documentation) */ ! 35: /* (unix is a trademark of Bell Laboratories) */ ! 36: static double stdf[ 26 ] = ! 37: { ! 38: 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, ! 39: 6.39, 0.04, 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, ! 40: 0.08, 6.63, 8.77, 9.68, 2.62, 0.81, 1.88, 0.23, ! 41: 2.07, 0.06, ! 42: }; ! 43: int obs[26]; ! 44: int bufsize; ! 45: int c, i, try; ! 46: double dot, winnerdot; /* .. */ ! 47: int winner, forced = 0; ! 48: char *inbuf; ! 49: ! 50: bufsize = 0; ! 51: if( argc > 1 ) ! 52: sscanf( argv[1], "%d", &forced ); ! 53: if( forced == 0 ) ! 54: forced = -1000; ! 55: ! 56: inbuf = calloc( BUFSIZ, 1 ); ! 57: ! 58: /* adjust frequency table to weight low probs REAL low */ ! 59: for (i=0; i<26; i++) { ! 60: stdf[i] = log(stdf[i]) + log(26.0/100.0); ! 61: } ! 62: ! 63: /* Decode each line separately */ ! 64: for (;;) { ! 65: for (i=0; i<=25; obs[i++]=0) ! 66: ; ! 67: ! 68: /* get a sample of the text */ ! 69: for( i = 0; i < BUFSIZ; i++ ) { ! 70: if( (c = getchar()) == EOF ) { ! 71: exit(0); ! 72: } ! 73: inbuf[i] = c; ! 74: if (c == '\n') { ! 75: bufsize = i+1; ! 76: break; ! 77: } ! 78: if (islower(c)) ! 79: obs[c-'a'] += 1; ! 80: else if (isupper(c)) ! 81: obs[c-'A'] += 1; ! 82: } ! 83: ! 84: /* now "dot" the freqs with the observed letter freqs */ ! 85: /* and keep track of best fit */ ! 86: winner = 0; ! 87: for (try = 0; try<26; try+=13) { ! 88: dot = 0; ! 89: for ( i=0; i<26; i++ ) { ! 90: dot += obs[i] * stdf[ (i+try) % 26 ]; ! 91: } ! 92: /* initialize winning score */ ! 93: if( try == 0 ) ! 94: winnerdot = dot; ! 95: if( dot > winnerdot ) { ! 96: /* got a new winner! */ ! 97: winner = try; ! 98: winnerdot = dot; ! 99: } ! 100: } ! 101: ! 102: if (forced != -1000) ! 103: winner = forced; ! 104: ! 105: /* print out sample buffer */ ! 106: for( i = 0; i < bufsize; i++ ) ! 107: putchar( rotate( inbuf[i], winner ) ); ! 108: } ! 109: } ! 110: ! 111: ! 112: static int ! 113: rotate( c, perm ) ! 114: char c; ! 115: int perm; ! 116: { ! 117: if (isupper(c)) { ! 118: return 'A' + (c - 'A' + perm) % 26 ; ! 119: } ! 120: else if (islower(c)) { ! 121: return 'a' + (c-'a'+perm) % 26 ; ! 122: } ! 123: else return c; ! 124: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.