12490Sjkh/* 22490Sjkh * Copyright (c) 1989, 1993 32490Sjkh * The Regents of the University of California. All rights reserved. 42490Sjkh * 52490Sjkh * This code is derived from software contributed to Berkeley by 62490Sjkh * Rick Adams. 72490Sjkh * 82490Sjkh * Authors: 92490Sjkh * Stan King, John Eldridge, based on algorithm suggested by 102490Sjkh * Bob Morris 112490Sjkh * 29-Sep-82 122490Sjkh * 132490Sjkh * Redistribution and use in source and binary forms, with or without 142490Sjkh * modification, are permitted provided that the following conditions 152490Sjkh * are met: 162490Sjkh * 1. Redistributions of source code must retain the above copyright 172490Sjkh * notice, this list of conditions and the following disclaimer. 182490Sjkh * 2. Redistributions in binary form must reproduce the above copyright 192490Sjkh * notice, this list of conditions and the following disclaimer in the 202490Sjkh * documentation and/or other materials provided with the distribution. 21203932Simp * 3. Neither the name of the University nor the names of its contributors 222490Sjkh * may be used to endorse or promote products derived from this software 232490Sjkh * without specific prior written permission. 242490Sjkh * 252490Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 262490Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 272490Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 282490Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 292490Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 302490Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 312490Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 322490Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 332490Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 342490Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 352490Sjkh * SUCH DAMAGE. 362490Sjkh */ 372490Sjkh 38114725Sobrien#if 0 392490Sjkh#ifndef lint 4015929Sachestatic const char copyright[] = 412490Sjkh"@(#) Copyright (c) 1989, 1993\n\ 422490Sjkh The Regents of the University of California. All rights reserved.\n"; 432490Sjkh#endif /* not lint */ 442490Sjkh 452490Sjkh#ifndef lint 4615929Sachestatic const char sccsid[] = "@(#)caesar.c 8.1 (Berkeley) 5/31/93"; 47114725Sobrien#endif /* not lint */ 4851287Speter#endif 49114725Sobrien#include <sys/cdefs.h> 50114725Sobrien__FBSDID("$FreeBSD$"); 512490Sjkh 5215929Sache#include <errno.h> 532490Sjkh#include <math.h> 542490Sjkh#include <stdio.h> 5515929Sache#include <stdlib.h> 5615929Sache#include <string.h> 572490Sjkh#include <ctype.h> 582490Sjkh#include <unistd.h> 592490Sjkh 602490Sjkh#define LINELENGTH 2048 612490Sjkh#define ROTATE(ch, perm) \ 6215929Sache isascii(ch) ? ( \ 632490Sjkh isupper(ch) ? ('A' + (ch - 'A' + perm) % 26) : \ 6415929Sache islower(ch) ? ('a' + (ch - 'a' + perm) % 26) : ch) : ch 652490Sjkh 662490Sjkh/* 672490Sjkh * letter frequencies (taken from some unix(tm) documentation) 682490Sjkh * (unix is a trademark of Bell Laboratories) 692490Sjkh */ 70227101Sedstatic double stdf[26] = { 712490Sjkh 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04, 722490Sjkh 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68, 732490Sjkh 2.62, 0.81, 1.88, 0.23, 2.07, 0.06, 742490Sjkh}; 752490Sjkh 76227101Sedstatic void printit(char *); 7715929Sache 7851287Speterint 79145782Sstefanfmain(int argc, char **argv) 802490Sjkh{ 8153210Sbillf int ch, dot, i, nread, winnerdot = 0; 8253210Sbillf char *inbuf; 832490Sjkh int obs[26], try, winner; 842490Sjkh 852490Sjkh if (argc > 1) 862490Sjkh printit(argv[1]); 872490Sjkh 8876885Skris if (!(inbuf = malloc((size_t)LINELENGTH))) { 892490Sjkh (void)fprintf(stderr, "caesar: out of memory.\n"); 902490Sjkh exit(1); 912490Sjkh } 922490Sjkh 932490Sjkh /* adjust frequency table to weight low probs REAL low */ 942490Sjkh for (i = 0; i < 26; ++i) 952490Sjkh stdf[i] = log(stdf[i]) + log(26.0 / 100.0); 962490Sjkh 972490Sjkh /* zero out observation table */ 982490Sjkh bzero(obs, 26 * sizeof(int)); 992490Sjkh 10076885Skris if ((nread = read(STDIN_FILENO, inbuf, (size_t)LINELENGTH)) < 0) { 1012490Sjkh (void)fprintf(stderr, "caesar: %s\n", strerror(errno)); 1022490Sjkh exit(1); 1032490Sjkh } 1042490Sjkh for (i = nread; i--;) { 10515929Sache ch = (unsigned char) inbuf[i]; 10615929Sache if (isascii(ch)) { 10715929Sache if (islower(ch)) 10815929Sache ++obs[ch - 'a']; 10915929Sache else if (isupper(ch)) 11015929Sache ++obs[ch - 'A']; 11115929Sache } 1122490Sjkh } 1132490Sjkh 1142490Sjkh /* 1152490Sjkh * now "dot" the freqs with the observed letter freqs 1162490Sjkh * and keep track of best fit 1172490Sjkh */ 1182490Sjkh for (try = winner = 0; try < 26; ++try) { /* += 13) { */ 1192490Sjkh dot = 0; 1202490Sjkh for (i = 0; i < 26; i++) 1212490Sjkh dot += obs[i] * stdf[(i + try) % 26]; 1222490Sjkh /* initialize winning score */ 1232490Sjkh if (try == 0) 1242490Sjkh winnerdot = dot; 1252490Sjkh if (dot > winnerdot) { 1262490Sjkh /* got a new winner! */ 1272490Sjkh winner = try; 1282490Sjkh winnerdot = dot; 1292490Sjkh } 1302490Sjkh } 1312490Sjkh 1322490Sjkh for (;;) { 1332490Sjkh for (i = 0; i < nread; ++i) { 13415929Sache ch = (unsigned char) inbuf[i]; 1352490Sjkh putchar(ROTATE(ch, winner)); 1362490Sjkh } 1372490Sjkh if (nread < LINELENGTH) 1382490Sjkh break; 13976885Skris if ((nread = read(STDIN_FILENO, inbuf, (size_t)LINELENGTH)) < 0) { 1402490Sjkh (void)fprintf(stderr, "caesar: %s\n", strerror(errno)); 1412490Sjkh exit(1); 1422490Sjkh } 1432490Sjkh } 1442490Sjkh exit(0); 1452490Sjkh} 1462490Sjkh 147227101Sedstatic void 148145782Sstefanfprintit(char *arg) 1492490Sjkh{ 15053210Sbillf int ch, rot; 1512490Sjkh 1522490Sjkh if ((rot = atoi(arg)) < 0) { 1532490Sjkh (void)fprintf(stderr, "caesar: bad rotation value.\n"); 1542490Sjkh exit(1); 1552490Sjkh } 1562490Sjkh while ((ch = getchar()) != EOF) 1572490Sjkh putchar(ROTATE(ch, rot)); 1582490Sjkh exit(0); 1592490Sjkh} 160