xref: /csrg-svn/usr.bin/cksum/crc.c (revision 63511)
147720Sbostic /*-
2*63511Sbostic  * Copyright (c) 1991, 1993
3*63511Sbostic  *	The Regents of the University of California.  All rights reserved.
447720Sbostic  *
547720Sbostic  * This code is derived from software contributed to Berkeley by
651066Sbostic  * James W. Williams of NASA Goddard Space Flight Center.
747720Sbostic  *
847720Sbostic  * %sccs.include.redist.c%
947720Sbostic  */
1047720Sbostic 
1147720Sbostic #ifndef lint
12*63511Sbostic static char sccsid[] = "@(#)crc.c	8.1 (Berkeley) 06/17/93";
1347720Sbostic #endif /* not lint */
1447720Sbostic 
1547720Sbostic #include <sys/types.h>
1647720Sbostic #include <unistd.h>
1747720Sbostic 
1851821Sbostic static u_long crctab[] = {
1951821Sbostic 	0x0,
2063510Sbostic 	0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
2163510Sbostic 	0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
2263510Sbostic 	0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
2363510Sbostic 	0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
2463510Sbostic 	0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
2563510Sbostic 	0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
2663510Sbostic 	0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
2763510Sbostic 	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
2863510Sbostic 	0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
2963510Sbostic 	0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
3063510Sbostic 	0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
3163510Sbostic 	0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
3263510Sbostic 	0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
3363510Sbostic 	0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
3463510Sbostic 	0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
3563510Sbostic 	0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
3663510Sbostic 	0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
3763510Sbostic 	0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
3863510Sbostic 	0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
3963510Sbostic 	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
4063510Sbostic 	0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
4163510Sbostic 	0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
4263510Sbostic 	0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
4363510Sbostic 	0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
4463510Sbostic 	0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
4563510Sbostic 	0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
4663510Sbostic 	0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
4763510Sbostic 	0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
4863510Sbostic 	0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
4963510Sbostic 	0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
5063510Sbostic 	0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
5163510Sbostic 	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
5263510Sbostic 	0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
5363510Sbostic 	0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
5463510Sbostic 	0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
5563510Sbostic 	0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
5663510Sbostic 	0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
5763510Sbostic 	0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
5863510Sbostic 	0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
5963510Sbostic 	0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
6063510Sbostic 	0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
6163510Sbostic 	0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
6263510Sbostic 	0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
6363510Sbostic 	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
6463510Sbostic 	0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
6563510Sbostic 	0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
6663510Sbostic 	0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
6763510Sbostic 	0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
6863510Sbostic 	0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
6963510Sbostic 	0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
7063510Sbostic 	0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
7147720Sbostic };
7247720Sbostic 
7347720Sbostic /*
7451883Sbostic  * Compute a POSIX 1003.2 checksum.  This routine has been broken out so that
7551883Sbostic  * other programs can use it.  It takes a file descriptor to read from and
7651883Sbostic  * locations to store the crc and the number of bytes read.  It returns 0 on
7751883Sbostic  * success and 1 on failure.  Errno is set on failure.
7847720Sbostic  */
7951883Sbostic u_long crc_total = ~0;			/* The crc over a number of files. */
8051883Sbostic 
8151821Sbostic int
crc(fd,cval,clen)8247720Sbostic crc(fd, cval, clen)
8347720Sbostic 	register int fd;
8447720Sbostic 	u_long *cval, *clen;
8547720Sbostic {
8647720Sbostic 	register u_char *p;
8751821Sbostic 	register int nr;
8851821Sbostic 	register u_long crc, len;
8951821Sbostic 	u_char buf[16 * 1024];
9047720Sbostic 
9151883Sbostic #define	COMPUTE(var, ch)	(var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
9251883Sbostic 
9351821Sbostic 	crc = len = 0;
9451883Sbostic 	crc_total = ~crc_total;
9547720Sbostic 	while ((nr = read(fd, buf, sizeof(buf))) > 0)
9651883Sbostic 		for (len += nr, p = buf; nr--; ++p) {
9751883Sbostic 			COMPUTE(crc, *p);
9851883Sbostic 			COMPUTE(crc_total, *p);
9951883Sbostic 		}
10047720Sbostic 	if (nr < 0)
10151883Sbostic 		return (1);
10247720Sbostic 
10351821Sbostic 	*clen = len;
10451821Sbostic 
10551821Sbostic 	/* Include the length of the file. */
10651883Sbostic 	for (; len != 0; len >>= 8) {
10751883Sbostic 		COMPUTE(crc, len & 0xff);
10851883Sbostic 		COMPUTE(crc_total, len & 0xff);
10951883Sbostic 	}
11051821Sbostic 
11151821Sbostic 	*cval = ~crc;
11251883Sbostic 	crc_total = ~crc_total;
11351883Sbostic 	return (0);
11447720Sbostic }
115