#!/bin/sh
# This is a shar archive.
# The rest of this file is a shell script which will extract:
#
# 4_12.in 4_12.text 4_12a.c 4_12a.cmp 4_12b.c 4_12b.cmp 4_12c.c 4_12d.c 4_12d.cmp makefile
#
# To extract the files from this shell archive file simply
# create a directory for this file, move the archive file
# to it and enter the command
#
#	sh filename
# 
# The files will be extracted automatically.
# Note: Do not use csh.
#
# Archive created: Mon Jul 30 23:00:15 EDT 1990
#
echo x - 4_12.in
sed 's/^X//' > 4_12.in << '!EOF!'
:GAGLG
S	NIAIA	
MLAN	yGLGG:		S
		GIA	SNS
IN5c	IAAA		SANGL
	]I$Nc
AISNNLNS	
!EOF!
ls -l 4_12.in
echo x - 4_12.text
sed 's/^X//' > 4_12.text << '!EOF!'
Ifsignalsaretobedisplayedinthepresenceofanenemy,theymustbeguardedbyciphers.Theciphersmustbecapableoffrequentchanges.Therulesbywhichthesechangesaremademustbecimple.Ciphersareundiscoverableinproportionastheirchangesarefrequentandasthemessagesineachchangearebrief.
!EOF!
ls -l 4_12.text
echo x - 4_12a.c
sed 's/^X//' > 4_12a.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include <ctype.h>

// print out a printable version of
// the character read in
int dochar()
{
    char c;
    if (!cin.get(c))
	return 0;

    if (isascii(c) && isprint(c))
	{
	cout.put(c);
	cout.put('_');
	}

    else
	cout << form("%2.2x", c);
    return 1;
}

// print a group of five characters
int dogroup()
{
    for (int chr_count = 5; chr_count-- > 0; )
	if (!dochar())
	    return 0;
    return 1;
}

// Print out six groups of characters separated
// by spaces. Precede each line with the count
// of characters printed so far.
int main(int, char**)
{
    for (int chr_cnt = 0; cin; chr_cnt += 30)
	{
	cout << dec(chr_cnt, 5) << "  ";

	for (int grp_count = 6;
	     grp_count-- > 0 && dogroup(); )
	    cout << "  ";

	cout << "\n";
	}
    return 0;
}
!EOF!
ls -l 4_12a.c
echo x - 4_12a.cmp
sed 's/^X//' > 4_12a.cmp << '!EOF!'
    0  :_0fG_1d08  0b1d080b1d  A_0d010cG_  1a0eL_110c  G_0a081f03  0506170408  
   30  S_17M_L_07  010217A_01  061a13N_03  09y_0e120f  1308160dG_  0c18L_100e  
   60  1e0909011a  G_03141f07  I_050bA_0f  1219060c0d  09S_0601N_  071e161812  
   90  0b0f18S_0a  0f0f0f0b16  1aI_N_5_04  16c_151b0d  091e0d09]_  I_$_071104  
  120  161b14N_08  18041e120b  0b0bA_051d  I_171c0e1c  1c1b13070e  02S_0814N_  
  150  150416A_0d  
!EOF!
ls -l 4_12a.cmp
echo x - 4_12b.c
sed 's/^X//' > 4_12b.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>

int main(int, char**)
{
    short count[0400];
    for (int i = 0; i < 0400; i++)
	count[i] = 0;

    unsigned char c;
    long total = 0;
    while (cin.get(c))
	{
	count[c]++;
	total++;
	}

    if (total > 0)
	for (i = 0; i < 0400; i++)
	    cout << i << "\t" << count[i] << "\t" <<
		(100.0 * count[i] / total) << "\n";

    return 0;
}
!EOF!
ls -l 4_12b.c
echo x - 4_12b.cmp
sed 's/^X//' > 4_12b.cmp << '!EOF!'
0	0	0
1	5	3.22581
2	2	1.29032
3	3	1.93548
4	5	3.22581
5	3	1.93548
6	4	2.58065
7	5	3.22581
8	7	4.51613
9	6	3.87097
10	2	1.29032
11	8	5.16129
12	4	2.58065
13	6	3.87097
14	5	3.22581
15	7	4.51613
16	1	0.645161
17	2	1.29032
18	4	2.58065
19	3	1.93548
20	3	1.93548
21	2	1.29032
22	6	3.87097
23	4	2.58065
24	4	2.58065
25	1	0.645161
26	4	2.58065
27	3	1.93548
28	3	1.93548
29	4	2.58065
30	4	2.58065
31	2	1.29032
32	0	0
33	0	0
34	0	0
35	0	0
36	1	0.645161
37	0	0
38	0	0
39	0	0
40	0	0
41	0	0
42	0	0
43	0	0
44	0	0
45	0	0
46	0	0
47	0	0
48	0	0
49	0	0
50	0	0
51	0	0
52	0	0
53	1	0.645161
54	0	0
55	0	0
56	0	0
57	0	0
58	1	0.645161
59	0	0
60	0	0
61	0	0
62	0	0
63	0	0
64	0	0
65	5	3.22581
66	0	0
67	0	0
68	0	0
69	0	0
70	0	0
71	5	3.22581
72	0	0
73	4	2.58065
74	0	0
75	0	0
76	3	1.93548
77	1	0.645161
78	5	3.22581
79	0	0
80	0	0
81	0	0
82	0	0
83	4	2.58065
84	0	0
85	0	0
86	0	0
87	0	0
88	0	0
89	0	0
90	0	0
91	0	0
92	0	0
93	1	0.645161
94	0	0
95	0	0
96	0	0
97	0	0
98	0	0
99	1	0.645161
100	0	0
101	0	0
102	0	0
103	0	0
104	0	0
105	0	0
106	0	0
107	0	0
108	0	0
109	0	0
110	0	0
111	0	0
112	0	0
113	0	0
114	0	0
115	0	0
116	0	0
117	0	0
118	0	0
119	0	0
120	0	0
121	1	0.645161
122	0	0
123	0	0
124	0	0
125	0	0
126	0	0
127	0	0
128	0	0
129	0	0
130	0	0
131	0	0
132	0	0
133	0	0
134	0	0
135	0	0
136	0	0
137	0	0
138	0	0
139	0	0
140	0	0
141	0	0
142	0	0
143	0	0
144	0	0
145	0	0
146	0	0
147	0	0
148	0	0
149	0	0
150	0	0
151	0	0
152	0	0
153	0	0
154	0	0
155	0	0
156	0	0
157	0	0
158	0	0
159	0	0
160	0	0
161	0	0
162	0	0
163	0	0
164	0	0
165	0	0
166	0	0
167	0	0
168	0	0
169	0	0
170	0	0
171	0	0
172	0	0
173	0	0
174	0	0
175	0	0
176	0	0
177	0	0
178	0	0
179	0	0
180	0	0
181	0	0
182	0	0
183	0	0
184	0	0
185	0	0
186	0	0
187	0	0
188	0	0
189	0	0
190	0	0
191	0	0
192	0	0
193	0	0
194	0	0
195	0	0
196	0	0
197	0	0
198	0	0
199	0	0
200	0	0
201	0	0
202	0	0
203	0	0
204	0	0
205	0	0
206	0	0
207	0	0
208	0	0
209	0	0
210	0	0
211	0	0
212	0	0
213	0	0
214	0	0
215	0	0
216	0	0
217	0	0
218	0	0
219	0	0
220	0	0
221	0	0
222	0	0
223	0	0
224	0	0
225	0	0
226	0	0
227	0	0
228	0	0
229	0	0
230	0	0
231	0	0
232	0	0
233	0	0
234	0	0
235	0	0
236	0	0
237	0	0
238	0	0
239	0	0
240	0	0
241	0	0
242	0	0
243	0	0
244	0	0
245	0	0
246	0	0
247	0	0
248	0	0
249	0	0
250	0	0
251	0	0
252	0	0
253	0	0
254	0	0
255	0	0
!EOF!
ls -l 4_12b.cmp
echo x - 4_12c.c
sed 's/^X//' > 4_12c.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include <sys/types.h>
typedef unsigned short ushort;
#include <sys/stat.h>
#include <memory.h>
#include <ctype.h>
#include <fcntl.h>
#include <osfcn.h>

int sizefile(char* filename)
{
    struct stat statbuf;
    if (stat(filename, &statbuf) != -1)
	return statbuf.st_size;
    else
	return 0;
}

void error(char* msg)
{
    cerr << msg << "\n";
    exit(1);
}

void readfile(char* filename, int filelen, char* filebfr)
{
    int fd = open(filename, O_RDONLY);
    if (fd < 0)
	error("cannot open file");
    if (read(fd, filebfr, filelen) != filelen)
	error("bytes read != size of file");
    close(fd);
}

int matchcount(char* bufptr1, char* bufptr2)
{
    int ctr = 0;
    while (*bufptr1++ == *bufptr2++)
	ctr++;
    return ctr;
}

void dochar(char c)
{
    if (isprint(c))
	{
	cout.put(c);
	cout.put('_');
	}
    else
	cout << form("%2.2x", c);
}

void prfactors(int max)
{
    int j = max / 2;
    for (int i = 2; i <= j; i++)
        if (max % i == 0)
	    cout << dec(i, 3);
    cout << dec(max, 3) << "\n";
}

void prperiods(int)
{
}

const int NUMperiods = 150;
struct
{
    int begin;
    int length;
} periodlist[NUMperiods] = { { -1, 0 } };

void addperiods(int begin, int interval, int cnt, int filelen)
{
    /* collapse old period info out */
    for (int left = 0; periodlist[left].begin != -1; left++)
	if (periodlist[left].begin < begin)
	    {
	    int right = left + 1;
	    periodlist[left] = periodlist[right];
	    for ( ; periodlist[right].begin != -1; )
	        if (periodlist[++right].begin >= begin)
		    periodlist[left++] = periodlist[right];
	    }
    
    /* At this point, periodlist[left].begin == -1. */
    /* We now add the new values. */
    for (int i = begin + 1; (left < NUMperiods) && (--cnt > 0); )
	for (int j = i; (j < filelen) && (left < NUMperiods); j += interval)
	    {
	    periodlist[left].begin = j;
	    periodlist[left++].length = cnt;
	    }

    if (left == NUMperiods)
        error("too many periods to add");
}

int foundperiod(int begin, int length)
{
    for (int i = 0; (i < NUMperiods) && (periodlist[i].begin != -1); i++)
	if ((periodlist[i].begin == begin) &&
	    (periodlist[i].length == length))
	    return 1;
    return 0;
}

void pr_common_periods()
{
}

main(int argc, char **argv)
{
    if (argc != 2)
	{
	cerr << "usage: " << argv[0] << " encrypted-file\n";
	return 1;
	}

    char* filename = argv[1];
    int filelen = sizefile(filename);
    char* filebfr = new char[filelen];
    readfile(filename, filelen, filebfr);

    cout << "length  string\n";
    cout << "1st pos  2nd pos  interval\n";
    cout << "factors  periods\n\n";
    for (int i = 0; i < filelen - 3; i++)
	{
	for (char* bufptr = &filebfr[i+3];
	     bufptr = memchr(bufptr,filebfr[i], filelen - (bufptr - filebfr));
	     bufptr++)
	    {
	    int cnt = matchcount(filebfr+i+1, bufptr+1);
	    if ((cnt > 2) && !foundperiod(i, cnt))
		{
		int interval = (bufptr - filebfr) - i;
		addperiods(i, interval, cnt, filelen);
		cout << cnt << "  ";
		for (char* p = bufptr; cnt--; p++ )
		    dochar(*p);
		cout << "\n" << i << "  " << (bufptr - filebfr) << "  " <<
		    interval << "\n";
		prfactors(interval);
		prperiods(interval);
		cout << "\n";
		break;
		}
	    }
	}

    pr_common_periods();
    return 0;
}
!EOF!
ls -l 4_12c.c
echo x - 4_12d.c
sed 's/^X//' > 4_12d.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include <stdlib.h>

main(int argc, char **argv)
{
    if (argc != 3)
	{
	cerr << "usage: " << argv[0] <<
	    " period char-index";
	return 1;
	}

    int period = atoi(argv[1]);
    int char_index = atoi(argv[2]);
    if ((char_index >= period) || (period <= 0) ||
	(char_index < 0))
	{
	cerr << "usage: " << argv[0] <<
	    " period char-index\n" <<
	    "\t0 < char-index < period\n";
	return 1;
	}

    short count[0400];
    for (int i = 0; i < 0400; i++)
	count[i] = 0;

    long total = 0;
    unsigned char c;
    for (i = 0; cin.get(c); i++)
	{
	if (i == period)
	    i = 0;

	if (i == char_index)
	    {
	    count[c]++;
	    total++;
	    }
	}

    for (i = 0; i < 0400; i++)
	cout << i << "\t" << count[i] <<  "\t" <<
	    (100.0 * count[i] / total) << "\n";

    return 0;
}
!EOF!
ls -l 4_12d.c
echo x - 4_12d.cmp
sed 's/^X//' > 4_12d.cmp << '!EOF!'
0	0	0
1	0	0
2	0	0
3	2	12.5
4	1	6.25
5	0	0
6	0	0
7	1	6.25
8	2	12.5
9	0	0
10	1	6.25
11	0	0
12	0	0
13	1	6.25
14	1	6.25
15	1	6.25
16	0	0
17	0	0
18	0	0
19	0	0
20	0	0
21	0	0
22	0	0
23	0	0
24	0	0
25	0	0
26	1	6.25
27	0	0
28	0	0
29	1	6.25
30	0	0
31	0	0
32	0	0
33	0	0
34	0	0
35	0	0
36	0	0
37	0	0
38	0	0
39	0	0
40	0	0
41	0	0
42	0	0
43	0	0
44	0	0
45	0	0
46	0	0
47	0	0
48	0	0
49	0	0
50	0	0
51	0	0
52	0	0
53	0	0
54	0	0
55	0	0
56	0	0
57	0	0
58	0	0
59	0	0
60	0	0
61	0	0
62	0	0
63	0	0
64	0	0
65	0	0
66	0	0
67	0	0
68	0	0
69	0	0
70	0	0
71	2	12.5
72	0	0
73	0	0
74	0	0
75	0	0
76	0	0
77	0	0
78	1	6.25
79	0	0
80	0	0
81	0	0
82	0	0
83	0	0
84	0	0
85	0	0
86	0	0
87	0	0
88	0	0
89	0	0
90	0	0
91	0	0
92	0	0
93	1	6.25
94	0	0
95	0	0
96	0	0
97	0	0
98	0	0
99	0	0
100	0	0
101	0	0
102	0	0
103	0	0
104	0	0
105	0	0
106	0	0
107	0	0
108	0	0
109	0	0
110	0	0
111	0	0
112	0	0
113	0	0
114	0	0
115	0	0
116	0	0
117	0	0
118	0	0
119	0	0
120	0	0
121	0	0
122	0	0
123	0	0
124	0	0
125	0	0
126	0	0
127	0	0
128	0	0
129	0	0
130	0	0
131	0	0
132	0	0
133	0	0
134	0	0
135	0	0
136	0	0
137	0	0
138	0	0
139	0	0
140	0	0
141	0	0
142	0	0
143	0	0
144	0	0
145	0	0
146	0	0
147	0	0
148	0	0
149	0	0
150	0	0
151	0	0
152	0	0
153	0	0
154	0	0
155	0	0
156	0	0
157	0	0
158	0	0
159	0	0
160	0	0
161	0	0
162	0	0
163	0	0
164	0	0
165	0	0
166	0	0
167	0	0
168	0	0
169	0	0
170	0	0
171	0	0
172	0	0
173	0	0
174	0	0
175	0	0
176	0	0
177	0	0
178	0	0
179	0	0
180	0	0
181	0	0
182	0	0
183	0	0
184	0	0
185	0	0
186	0	0
187	0	0
188	0	0
189	0	0
190	0	0
191	0	0
192	0	0
193	0	0
194	0	0
195	0	0
196	0	0
197	0	0
198	0	0
199	0	0
200	0	0
201	0	0
202	0	0
203	0	0
204	0	0
205	0	0
206	0	0
207	0	0
208	0	0
209	0	0
210	0	0
211	0	0
212	0	0
213	0	0
214	0	0
215	0	0
216	0	0
217	0	0
218	0	0
219	0	0
220	0	0
221	0	0
222	0	0
223	0	0
224	0	0
225	0	0
226	0	0
227	0	0
228	0	0
229	0	0
230	0	0
231	0	0
232	0	0
233	0	0
234	0	0
235	0	0
236	0	0
237	0	0
238	0	0
239	0	0
240	0	0
241	0	0
242	0	0
243	0	0
244	0	0
245	0	0
246	0	0
247	0	0
248	0	0
249	0	0
250	0	0
251	0	0
252	0	0
253	0	0
254	0	0
255	0	0
!EOF!
ls -l 4_12d.cmp
echo x - makefile
sed 's/^X//' > makefile << '!EOF!'
CC= CC -I. -I../../CC
CFLAGS=

all: 4_12a 4_12b 4_12d

4_12a: 4_12a.c
	$(CC) 4_12a.c -o 4_12a

4_12b: 4_12b.c
	$(CC) 4_12b.c -o 4_12b

4_12d: 4_12d.c
	$(CC) 4_12d.c -o 4_12d

OUT= 4_12a.out 4_12b.out 4_12d.out
CMP= 4_12a.cmp 4_12b.cmp 4_12d.cmp

4_12a.out: 4_12a 4_12.in ;	4_12a < 4_12.in > 4_12a.out
4_12b.out: 4_12b 4_12.in ;	4_12b < 4_12.in > 4_12b.out
4_12d.out: 4_12d 4_12.in ;	4_12d 10 4 < 4_12.in > 4_12d.out

test: all $(OUT) $(CMP)
	cmp 4_12a.out 4_12a.cmp
	cmp 4_12b.out 4_12b.cmp
	cmp 4_12d.out 4_12d.cmp
	echo tests done
!EOF!
ls -l makefile
# The following exit is to ensure that extra garbage 
# after the end of the shar file will be ignored.
exit 0
