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
rotate defined in line 112; used 1 times

Defined variables

SccsId defined in line 22; never used
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 991
Valid CSS Valid XHTML 1.0 Strict