1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40: #include <sys/cdefs.h>
41: #ifndef lint
42: __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
43: The Regents of the University of California. All rights reserved.\n");
44: #endif
45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)caesar.c 8.1 (Berkeley) 5/31/93";
49: #else
50: __RCSID("$NetBSD: caesar.c,v 1.14 2004/01/27 20:30:29 jsm Exp $");
51: #endif
52: #endif
53:
54: #include <ctype.h>
55: #include <err.h>
56: #include <errno.h>
57: #include <math.h>
58: #include <stdio.h>
59: #include <string.h>
60: #include <stdlib.h>
61: #include <unistd.h>
62:
63: #define LINELENGTH 2048
64: #define ROTATE(ch, perm) \
65: isupper(ch) ? ('A' + (ch - 'A' + perm) % 26) : \
66: islower(ch) ? ('a' + (ch - 'a' + perm) % 26) : ch
67:
68:
69:
70:
71:
72: double stdf[26] = {
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,
76: };
77:
78:
79: int main(int, char *[]);
80: void printit(const char *) __attribute__((__noreturn__));
81:
82: int
83: main(argc, argv)
84: int argc;
85: char **argv;
86: {
87: int ch, i, nread;
88: double dot, winnerdot;
89: char *inbuf;
90: int obs[26], try, winner;
91:
92:
93: setregid(getgid(), getgid());
94:
95: winnerdot = 0;
96: if (argc > 1)
97: printit(argv[1]);
98:
99: if (!(inbuf = malloc(LINELENGTH)))
100: err(1, NULL);
101:
102:
103: for (i = 0; i < 26; ++i)
104: stdf[i] = log(stdf[i]) + log(26.0 / 100.0);
105:
106:
107: memset(obs, 0, 26 * sizeof(int));
108:
109: if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0)
110: err(1, "reading from stdin");
111: for (i = nread; i--;) {
112: ch = inbuf[i];
113: if (islower(ch))
114: ++obs[ch - 'a'];
115: else if (isupper(ch))
116: ++obs[ch - 'A'];
117: }
118:
119:
120:
121:
122:
123: for (try = winner = 0; try < 26; ++try) {
124: dot = 0;
125: for (i = 0; i < 26; i++)
126: dot += obs[i] * stdf[(i + try) % 26];
127:
128: if (try == 0)
129: winnerdot = dot;
130: if (dot > winnerdot) {
131:
132: winner = try;
133: winnerdot = dot;
134: }
135: }
136:
137: for (;;) {
138: for (i = 0; i < nread; ++i) {
139: ch = inbuf[i];
140: putchar(ROTATE(ch, winner));
141: }
142: if (nread < LINELENGTH)
143: break;
144: if ((nread = read(STDIN_FILENO, inbuf, LINELENGTH)) < 0)
145: err(1, "reading from stdin");
146: }
147: exit(0);
148: }
149:
150: void
151: printit(arg)
152: const char *arg;
153: {
154: int ch, rot;
155:
156: if ((rot = atoi(arg)) < 0)
157: errx(1, "bad rotation value.");
158: while ((ch = getchar()) != EOF)
159: putchar(ROTATE(ch, rot));
160: exit(0);
161: }