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: }
Defined functions
main
defined in line
30;
never used
Defined variables