caesar.c revision 53210
1132718Skan/* 2132718Skan * Copyright (c) 1989, 1993 3169689Skan * The Regents of the University of California. All rights reserved. 4132718Skan * 5132718Skan * This code is derived from software contributed to Berkeley by 6132718Skan * Rick Adams. 7132718Skan * 8132718Skan * Authors: 9132718Skan * Stan King, John Eldridge, based on algorithm suggested by 10132718Skan * Bob Morris 11132718Skan * 29-Sep-82 12132718Skan * 13132718Skan * Redistribution and use in source and binary forms, with or without 14132718Skan * modification, are permitted provided that the following conditions 15132718Skan * are met: 16132718Skan * 1. Redistributions of source code must retain the above copyright 17132718Skan * notice, this list of conditions and the following disclaimer. 18132718Skan * 2. Redistributions in binary form must reproduce the above copyright 19132718Skan * notice, this list of conditions and the following disclaimer in the 20169689Skan * documentation and/or other materials provided with the distribution. 21169689Skan * 3. All advertising materials mentioning features or use of this software 22132718Skan * must display the following acknowledgement: 23132718Skan * This product includes software developed by the University of 24132718Skan * California, Berkeley and its contributors. 25132718Skan * 4. Neither the name of the University nor the names of its contributors 26132718Skan * may be used to endorse or promote products derived from this software 27132718Skan * without specific prior written permission. 28169689Skan * 29132718Skan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30132718Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31132718Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32132718Skan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33132718Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34132718Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35169689Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36169689Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37132718Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38132718Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39132718Skan * SUCH DAMAGE. 40132718Skan * 41132718Skan * $FreeBSD: head/games/caesar/caesar.c 53210 1999-11-16 02:58:06Z billf $ 42169689Skan */ 43169689Skan 44169689Skan#ifndef lint 45132718Skanstatic const char copyright[] = 46132718Skan"@(#) Copyright (c) 1989, 1993\n\ 47132718Skan The Regents of the University of California. All rights reserved.\n"; 48132718Skan#endif /* not lint */ 49132718Skan 50169689Skan#ifndef lint 51132718Skan#if 0 52169689Skanstatic const char sccsid[] = "@(#)caesar.c 8.1 (Berkeley) 5/31/93"; 53132718Skan#else 54132718Skanstatic const char rcsid[] = 55169689Skan "$FreeBSD: head/games/caesar/caesar.c 53210 1999-11-16 02:58:06Z billf $"; 56132718Skan#endif 57169689Skan#endif /* not lint */ 58132718Skan 59169689Skan#include <errno.h> 60169689Skan#include <math.h> 61169689Skan#include <stdio.h> 62169689Skan#include <stdlib.h> 63132718Skan#include <string.h> 64132718Skan#include <ctype.h> 65132718Skan#include <unistd.h> 66132718Skan 67132718Skan#define LINELENGTH 2048 68132718Skan#define ROTATE(ch, perm) \ 69132718Skan isascii(ch) ? ( \ 70132718Skan isupper(ch) ? ('A' + (ch - 'A' + perm) % 26) : \ 71132718Skan islower(ch) ? ('a' + (ch - 'a' + perm) % 26) : ch) : ch 72132718Skan 73132718Skan/* 74132718Skan * letter frequencies (taken from some unix(tm) documentation) 75132718Skan * (unix is a trademark of Bell Laboratories) 76132718Skan */ 77double stdf[26] = { 78 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04, 79 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68, 80 2.62, 0.81, 1.88, 0.23, 2.07, 0.06, 81}; 82 83void printit(); 84 85int 86main(argc, argv) 87 int argc; 88 char **argv; 89{ 90 int ch, dot, i, nread, winnerdot = 0; 91 char *inbuf; 92 int obs[26], try, winner; 93 94 /* revoke setgid privileges */ 95 setgid(getgid()); 96 97 if (argc > 1) 98 printit(argv[1]); 99 100 if (!(inbuf = malloc(LINELENGTH))) { 101 (void)fprintf(stderr, "caesar: out of memory.\n"); 102 exit(1); 103 } 104 105 /* adjust frequency table to weight low probs REAL low */ 106 for (i = 0; i < 26; ++i) 107 stdf[i] = log(stdf[i]) + log(26.0 / 100.0); 108 109 /* zero out observation table */ 110 bzero(obs, 26 * sizeof(int)); 111 112 if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0) { 113 (void)fprintf(stderr, "caesar: %s\n", strerror(errno)); 114 exit(1); 115 } 116 for (i = nread; i--;) { 117 ch = (unsigned char) inbuf[i]; 118 if (isascii(ch)) { 119 if (islower(ch)) 120 ++obs[ch - 'a']; 121 else if (isupper(ch)) 122 ++obs[ch - 'A']; 123 } 124 } 125 126 /* 127 * now "dot" the freqs with the observed letter freqs 128 * and keep track of best fit 129 */ 130 for (try = winner = 0; try < 26; ++try) { /* += 13) { */ 131 dot = 0; 132 for (i = 0; i < 26; i++) 133 dot += obs[i] * stdf[(i + try) % 26]; 134 /* initialize winning score */ 135 if (try == 0) 136 winnerdot = dot; 137 if (dot > winnerdot) { 138 /* got a new winner! */ 139 winner = try; 140 winnerdot = dot; 141 } 142 } 143 144 for (;;) { 145 for (i = 0; i < nread; ++i) { 146 ch = (unsigned char) inbuf[i]; 147 putchar(ROTATE(ch, winner)); 148 } 149 if (nread < LINELENGTH) 150 break; 151 if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0) { 152 (void)fprintf(stderr, "caesar: %s\n", strerror(errno)); 153 exit(1); 154 } 155 } 156 exit(0); 157} 158 159void printit(arg) 160 char *arg; 161{ 162 int ch, rot; 163 164 if ((rot = atoi(arg)) < 0) { 165 (void)fprintf(stderr, "caesar: bad rotation value.\n"); 166 exit(1); 167 } 168 while ((ch = getchar()) != EOF) 169 putchar(ROTATE(ch, rot)); 170 exit(0); 171} 172