]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - caesar/caesar.c
1 /* $NetBSD: caesar.c,v 1.15 2005/05/23 23:02:30 rillig Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
11 * Stan King, John Eldridge, based on algorithm suggested by
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #include <sys/cdefs.h>
43 __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
44 The Regents of the University of California. All rights reserved.\n");
49 static char sccsid
[] = "@(#)caesar.c 8.1 (Berkeley) 5/31/93";
51 __RCSID("$NetBSD: caesar.c,v 1.15 2005/05/23 23:02:30 rillig Exp $");
65 #define NCHARS (1 << CHAR_BIT)
69 * letter frequencies (taken from some unix(tm) documentation)
70 * (unix is a trademark of Bell Laboratories)
72 static const unsigned char upper
[LETTERS
] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
73 static const unsigned char lower
[LETTERS
] = "abcdefghijklmnopqrstuvwxyz";
74 static double stdf
[LETTERS
] = {
75 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04,
76 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68,
77 2.62, 0.81, 1.88, 0.23, 2.07, 0.06
80 static unsigned char rottbl
[NCHARS
];
90 for (i
= 0; i
< NCHARS
; i
++)
91 rottbl
[i
] = (unsigned char)i
;
93 for (i
= 0; i
< LETTERS
; i
++)
94 rottbl
[upper
[i
]] = upper
[(i
+ rot
) % LETTERS
];
96 for (i
= 0; i
< LETTERS
; i
++)
97 rottbl
[lower
[i
]] = lower
[(i
+ rot
) % LETTERS
];
100 static void __attribute__((__noreturn__
))
101 printrot(const char *arg
)
108 rot
= strtol(arg
, &endp
, 10);
110 errx(EXIT_FAILURE
, "bad rotation value: %s", arg
);
113 if (errno
== ERANGE
|| rot
< 0 || rot
> INT_MAX
) {
114 errx(EXIT_FAILURE
, "rotation value out of range: %s", arg
);
117 init_rottbl((int)rot
);
119 while ((ch
= getchar()) != EOF
) {
120 if (putchar(rottbl
[ch
]) == EOF
) {
121 err(EXIT_FAILURE
, "writing to stdout");
130 main(int argc
, char **argv
)
132 ssize_t i
, nread
, ntotal
;
133 double dot
, winnerdot
;
135 unsigned char inbuf
[2048];
136 unsigned int obs
[NCHARS
];
138 /* revoke setgid privileges */
139 (void)setgid(getgid());
146 /* adjust frequency table to weight low probs REAL low */
147 for (i
= 0; i
< LETTERS
; i
++)
148 stdf
[i
] = log(stdf
[i
]) + log(LETTERS
/ 100.0);
150 /* zero out observation table */
151 (void)memset(obs
, 0, sizeof(obs
));
153 for (ntotal
= 0; (size_t) ntotal
< sizeof(inbuf
); ntotal
+= nread
) {
154 nread
= read(STDIN_FILENO
, &inbuf
[ntotal
],
155 sizeof(inbuf
) - ntotal
);
157 err(EXIT_FAILURE
, "reading from stdin");
164 for (i
= 0; i
< ntotal
; i
++)
168 * now "dot" the freqs with the observed letter freqs
169 * and keep track of best fit
173 for (try = 0; try < LETTERS
; try++) {
175 for (i
= 0; i
< LETTERS
; i
++)
176 dot
+= (obs
[upper
[i
]] + obs
[lower
[i
]])
177 * stdf
[(i
+ try) % LETTERS
];
179 if (try == 0 || dot
> winnerdot
) {
180 /* got a new winner! */
188 for (i
= 0; i
< ntotal
; i
++) {
189 if (putchar(rottbl
[inbuf
[i
]]) == EOF
) {
190 err(EXIT_FAILURE
, "writing to stdout");
194 if ((ntotal
= read(STDIN_FILENO
, inbuf
, sizeof(inbuf
))) < 0) {
195 err(EXIT_FAILURE
, "reading from stdin");