|
|
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.