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