home *** CD-ROM | disk | FTP | other *** search
- /*
- ** crc16.c -- calculate 16-bit CRC for file(s)
- ** rev. Feb. 1992
- ** public domain by Raymond Gardner
- ** Englewood, Colorado
- **
- ** This program uses the same CRC calculation as ARC (SEA) and LHA (Yoshi)
- */
-
- #include <stdio.h>
- #include <stdlib.h>
-
- typedef unsigned short WORD; /* 'WORD' must be 16-bit unsigned (for crc) */
-
- #define bufsiz (16*1024)
-
- WORD crc_table[256];
-
- /*
- ** I determined this function empirically, by examining the
- ** table for patterns, and programming via trial-and-error.
- ** Don't ask me how it works or if it can be generalized for
- ** other CRC polynomials.
- */
-
- void init_crc_table()
- {
- int i, j;
- WORD k;
-
- for (i = 0; i < 256; i++)
- {
- k = 0xC0C1;
- for (j = 1; j < 256; j <<= 1)
- {
- if (i & j)
- crc_table[i] ^= k;
- k = (k << 1) ^ 0x4003;
- }
- }
- }
-
- /*
- ** crc_calc() -- calculate cumulative crc-16 for buffer
- */
-
- WORD crc_calc(WORD crc, char *buf, unsigned nbytes)
- {
- unsigned char *p, *lim;
-
- p = (unsigned char *)buf;
- lim = p + nbytes;
- while (p < lim)
- {
- crc = (crc >> 8 ) ^ crc_table[(crc & 0xFF) ^ *p++];
- }
- return crc;
- }
-
- void do_file(char *fn)
- {
- static char buf[bufsiz];
- FILE *f;
- int k;
- WORD crc;
-
- f = fopen(fn, "rb");
- if (f == NULL)
- {
- printf("%s: can't open file\n", fn);
- return;
- }
- crc = 0;
- while ((k = fread(buf, 1, bufsiz, f)) != 0)
- crc = crc_calc(crc, buf, k);
- fclose(f);
- printf("%-14s %04X\n", fn, crc);
- }
-
- int main(int argc, char **argv)
- {
- int i;
-
- if (argc < 2)
- {
- fprintf(stderr, "Usage: crc filename [filename...]\n");
- return EXIT_FAILURE;
- }
- init_crc_table();
- for (i = 1; i < argc; i++)
- do_file(argv[i]);
- return EXIT_SUCCESS;
- }
-