]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - caesar/caesar.c
1 /* $NetBSD: caesar.c,v 1.23 2021/05/01 20:21:25 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\
44 The Regents of the University of California. All rights reserved.");
49 static char sccsid
[] = "@(#)caesar.c 8.1 (Berkeley) 5/31/93";
51 __RCSID("$NetBSD: caesar.c,v 1.23 2021/05/01 20:21:25 rillig Exp $");
63 #define NCHARS (1 << CHAR_BIT)
67 * letter frequencies (taken from some unix(tm) documentation)
68 * (unix is a trademark of Bell Laboratories)
70 static const unsigned char upper
[LETTERS
] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
71 static const unsigned char lower
[LETTERS
] = "abcdefghijklmnopqrstuvwxyz";
72 static double stdf
[LETTERS
] = {
73 7.97, 1.35, 3.61, 4.78, 12.37, 2.01, 1.46, 4.49, 6.39, 0.04,
74 0.42, 3.81, 2.69, 5.92, 6.96, 2.91, 0.08, 6.63, 8.77, 9.68,
75 2.62, 0.81, 1.88, 0.23, 2.07, 0.06
78 static unsigned char rottbl
[NCHARS
];
82 init_rottbl(unsigned int rot
)
86 rot
%= LETTERS
; /* prevent integer overflow */
88 for (i
= 0; i
< NCHARS
; i
++)
89 rottbl
[i
] = (unsigned char)i
;
91 for (i
= 0; i
< LETTERS
; i
++)
92 rottbl
[upper
[i
]] = upper
[(i
+ rot
) % LETTERS
];
94 for (i
= 0; i
< LETTERS
; i
++)
95 rottbl
[lower
[i
]] = lower
[(i
+ rot
) % LETTERS
];
103 while ((ch
= getchar()) != EOF
) {
104 if (putchar(rottbl
[ch
]) == EOF
) {
105 err(EXIT_FAILURE
, "<stdout>");
112 print_array(const unsigned char *a
, size_t len
)
116 for (i
= 0; i
< len
; i
++) {
117 if (putchar(rottbl
[a
[i
]]) == EOF
) {
118 err(EXIT_FAILURE
, "<stdout>");
125 get_rotation(const char *arg
)
131 rot
= strtol(arg
, &endp
, 10);
132 if (errno
== 0 && (arg
[0] == '\0' || *endp
!= '\0'))
134 if (errno
== 0 && (rot
< 0 || rot
> INT_MAX
))
137 err(EXIT_FAILURE
, "Bad rotation value `%s'", arg
);
138 return (unsigned int)rot
;
142 guess_and_rotate(void)
144 unsigned char inbuf
[2048];
145 unsigned int obs
[NCHARS
];
147 double dot
, winnerdot
;
148 unsigned int try, winner
;
151 /* adjust frequency table to weight low probs REAL low */
152 for (i
= 0; i
< LETTERS
; i
++)
153 stdf
[i
] = log(stdf
[i
]) + log(LETTERS
/ 100.0);
155 /* zero out observation table */
156 (void)memset(obs
, 0, sizeof(obs
));
158 for (nread
= 0; nread
< sizeof(inbuf
); nread
++) {
159 if ((ch
= getchar()) == EOF
)
161 inbuf
[nread
] = (unsigned char) ch
;
164 for (i
= 0; i
< nread
; 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! */
187 print_array(inbuf
, nread
);
192 main(int argc
, char **argv
)
197 } else if (argc
== 2) {
198 init_rottbl(get_rotation(argv
[1]));
201 (void)fprintf(stderr
, "usage: caesar [rotation]\n");
207 errx(EXIT_FAILURE
, "<stdin>");
211 (void)fflush(stdout
);
212 if (ferror(stdout
)) {
213 errx(EXIT_FAILURE
, "<stdout>");