xref: /plan9/sys/src/cmd/sum.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 #include <u.h>
2 #include <libc.h>
3 
4 typedef ulong	Sumfn(ulong, void*, uvlong);
5 extern Sumfn	sumr, sum5, sum32;
6 char		*sumfile(char*, Sumfn*);
7 
8 void
usage(void)9 usage(void)
10 {
11 	fprint(2, "Usage: %s [-r5] [files]\n", argv0);
12 	exits("usage");
13 }
14 
15 void
main(int argc,char ** argv)16 main(int argc, char **argv)
17 {
18 	Sumfn *fn = sum32;
19 	char *exitstr=0, *s;
20 
21 	ARGBEGIN{
22 	case 'r':
23 		fn = sumr;
24 		break;
25 	case '5':
26 		fn = sum5;
27 		break;
28 	default:
29 		usage();
30 		break;
31 	}ARGEND
32 	if(*argv){
33 		while(*argv)
34 			if(s = sumfile(*argv++, fn))	/* assign = */
35 				exitstr = s;
36 	}else
37 		exitstr = sumfile(0, fn);
38 	exits(exitstr);
39 }
40 
41 char*
sumfile(char * file,Sumfn * fn)42 sumfile(char *file, Sumfn *fn)
43 {
44 	int fd;
45 	int n;
46 	ulong sum;
47 	uvlong fsize;
48 	char buf[8*1024];
49 
50 	if(file){
51 		if((fd = open(file, OREAD)) < 0){
52 			errstr(buf, sizeof buf);
53 			fprint(2, "%s: %s: %s\n", argv0, file, buf);
54 			return "can't open";
55 		}
56 	}else
57 		fd = 0;
58 	fsize = 0;
59 	sum = 0;
60 	while((n=read(fd, buf, sizeof buf)) > 0){
61 		fsize += n;
62 		sum = (*fn)(sum, buf, n);
63 	}
64 	if(n < 0){
65 		errstr(buf, sizeof buf);
66 		fprint(2, "%s: %s: read error: %s\n", argv0, file? file:"<stdin>", buf);
67 		if(file)
68 			close(fd);
69 		return "read error";
70 	}
71 	if(file)
72 		close(fd);
73 	(*fn)(sum, (char*)0, fsize);
74 	if(file)
75 		print(" %s", file);
76 	print("\n");
77 	return 0;
78 }
79 
80 #define	VBSIZE		512		/* system v */
81 
82 ulong
sum5(ulong sum,void * buf,uvlong uvn)83 sum5(ulong sum, void *buf, uvlong uvn)
84 {
85 	uchar *s, *send;
86 	int n;
87 
88 	if(buf == 0){
89 		sum = ((sum>>16)+sum) & 0xFFFF;
90 		print("%.5lud%6lld", sum, (uvn+(VBSIZE-1))/VBSIZE);
91 		return 0;
92 	}
93 	n = uvn;
94 	for(s=buf, send=s+n; s<send; s++)
95 		sum += 0xffff & *s;
96 	return sum;
97 }
98 
99 #define	RBSIZE		1024		/* research */
100 
101 ulong
sumr(ulong sum,void * buf,uvlong uvn)102 sumr(ulong sum, void *buf, uvlong uvn)
103 {
104 	uchar *s, *send;
105 	int n;
106 
107 	if(buf == 0){
108 		sum &= 0xFFFF;
109 		print("%.5lud%6lld", sum, (uvn+(RBSIZE-1))/RBSIZE);
110 		return 0;
111 	}
112 	n = uvn;
113 	for(s=buf, send=s+n; s<send; s++)
114 		if(sum & 1)
115 			sum = 0xffff & ((sum>>1)+*s+0x8000);
116 		else
117 			sum = 0xffff & ((sum>>1)+*s);
118 	return sum;
119 }
120 
121 extern ulong crc_table[256];
122 
123 ulong
sum32(ulong lcrc,void * buf,uvlong uvn)124 sum32(ulong lcrc, void *buf, uvlong uvn)
125 {
126 	uchar *s = buf;
127 	ulong crc = lcrc;
128 	int n;
129 
130 	n = uvn;
131 	if(buf == 0){
132 		char x[4];
133 
134 		x[0] = (n>>24)^0xCC;	/* encode the length but make n==0 not 0 */
135 		x[1] = (n>>16)^0x55;
136 		x[2] = (n>>8)^0xCC;
137 		x[3] = (n)^0x55;
138 		crc = sum32(lcrc, x, 4);
139 		print("%.8lux %6lld", crc, uvn);
140 		return 0;
141 	}
142 	while(n-- > 0)
143 		crc = crc_table[(crc^*s++)&0xff] ^ (crc>>8);
144 	return crc;
145 }
146 
147 /*
148  *	CRC 035556101440
149  */
150 ulong crc_table[256] = {
151 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
152 	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
153 	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
154 	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
155 	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
156 	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
157 	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
158 	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
159 	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
160 	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
161 	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
162 	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
163 	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
164 	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
165 	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
166 	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
167 	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
168 	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
169 	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
170 	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
171 	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
172 	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
173 	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
174 	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
175 	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
176 	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
177 	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
178 	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
179 	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
180 	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
181 	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
182 	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
183 	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
184 	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
185 	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
186 	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
187 	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
188 	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
189 	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
190 	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
191 	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
192 	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
193 	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
194 	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
195 	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
196 	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
197 	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
198 	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
199 	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
200 	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
201 	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
202 	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
203 	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
204 	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
205 	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
206 	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
207 	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
208 	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
209 	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
210 	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
211 	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
212 	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
213 	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
214 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
215 };
216