home *** CD-ROM | disk | FTP | other *** search
- From decwrl!wyse!uunet!allbery Sun Jan 29 20:30:28 PST 1989
- Article 798 of comp.sources.misc:
- Path: granite!decwrl!wyse!uunet!allbery
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Newsgroups: comp.sources.misc
- Subject: v06i025: Yet Another Checksumming Program
- Message-ID: <47757@uunet.UU.NET>
- Date: 29 Jan 89 21:16:48 GMT
- Sender: allbery@uunet.UU.NET
- Reply-To: naz@hslrswi.UUCP (Norman H. Azadian)
- Lines: 900
- Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- X-Arch-Keywords: c, bsd, ibmpc, crc-32
-
- Posting-number: Volume 6, Issue 25
- Submitted-by: naz@hslrswi.UUCP (Norman H. Azadian)
- Archive-name: chksum
-
- #--------------------------------CUT HERE-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # -rw-r--r-- 1 naz 1991 Jan 25 15:14 readme
- # -rw-r--r-- 1 naz 536 Jan 25 15:05 makefile
- # -rw-r--r-- 1 naz 436 Jan 25 14:53 debug.h
- # -rw-r--r-- 1 naz 2837 Jan 25 14:41 gen.h
- # -rw-r--r-- 1 naz 8136 Jan 25 14:41 chksum.c
- # -rw-r--r-- 1 naz 11016 Jan 25 15:14 crc32.c
- #
- echo 'x - readme'
- if test -f readme; then echo 'shar: not overwriting readme'; else
- sed 's/^X//' << '________This_Is_The_END________' > readme
- X
- XChksum is a little program that I've developed and used a lot over the
- Xyears. The prime difference between it and the ones that it copies, is
- Xthat it can read a list of pathnames from stdin. This turns out to be
- Xvery handy indeed. Also, it uses a 32-bit CRC, which means that a false
- Xmatch is 2**16 times less likely than with the 16-bit brands. It
- Xproduces identical results on both PCs and VAXen.
- X
- XThe 32-bit CRC routine was donated by kind souls on the net. I have
- Xtweaked it for my use, principally by adding inline optimized assembly
- Xcode for my PC. I don't pretend to know what is going on inside, and I
- Xregard it as a minor miracle that it actually produces the same numbers
- Xon PCs as on VAXen. Perhaps somebody will tell me if it produces the
- X"right" numbers.
- X
- XI've developed it on an Aztec C compiler, currently version 4.10a. You
- Xshouldn't have much trouble porting it to your favorite compiler. I
- Xhave found that on the VAX I had to comment-out the #asm stuff in
- Xcrc32.c, in spite of the fact that it is already conditionally compiled
- Xout. I have stubbed-out my debugging stuff, so the printd()'s and
- Xinitdebug() won't produce any code.
- X
- XIf you don't have string.h, then you probably don't have the string
- Xlibrary either. No sweat, all you need do is delete the include for
- Xstring.h, and add the following routine to chksum.c:
- X
- X local void strcpy(dst, src)
- X char *dst, *src;
- X {
- X while ((*dst++ = *src++) != '\0')
- X continue;
- X }
- X
- XYou'll need to remove the reference to the library in the makefile too.
- XIf all else fails, the DOS executable is now available at fine
- Xcomp.binaries.pc newsgroups everywhere.
- X
- XI hereby donate this program to the Public Domain for any and all
- Xpurposes. Enjoy.
- X
- XHere is the output of "chksum -v *.h *.c makefile":
- X
- X26b5c1c7 436 debug.h
- X02180ae4 2837 gen.h
- X872b0f18 8136 chksum.c
- X6d239b68 11016 crc32.c
- X44bdd9f4 536 makefile
- X====================
- X86c94990 22961 Grand Totals for 5 files
- ________This_Is_The_END________
- if test `wc -c < readme` -ne 1991; then
- echo 'shar: readme was damaged during transit (should have been 1991 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - makefile'
- if test -f makefile; then echo 'shar: not overwriting makefile'; else
- sed 's/^X//' << '________This_Is_The_END________' > makefile
- X# /usr/bin/src 870407 NHA
- X
- X#this is for 4.3bsd
- XCOPT= -O
- XCFLAGS= -I. -c
- XLNFLAGS= -o chksum
- XCC= /bin/cc
- XLN= /bin/cc
- X
- X#this is for the Aztec version 4.10a under DOS
- X#AOPT= -186
- X#COPT= +a +2
- X#AFLAGS= -DMODEL=3 $(AOPT)
- X#CFLAGS= -I. -ansi -c +l +b $(COPT)
- X#LNFLAGS= -t -g
- X#LIBS= -lstringl -lcl
- X#CC= /manx/cc.exe
- X#LN= ln
- X#RM= del
- X
- X.c.o:
- X ${CC} ${CFLAGS} $<
- X
- X.c.asm:
- X ${CC} -at ${CFLAGS} $<
- X
- X
- Xchksum.exe: chksum.o crc32.o
- X $(LN) $(LNFLAGS) chksum.o crc32.o $(LIBS)
- X
- Xclean:
- X -rm *.o
- X -rm *.sym
- X -rm *.dbg
- X -rm chksum.exe
- ________This_Is_The_END________
- if test `wc -c < makefile` -ne 536; then
- echo 'shar: makefile was damaged during transit (should have been 536 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - debug.h'
- if test -f debug.h; then echo 'shar: not overwriting debug.h'; else
- sed 's/^X//' << '________This_Is_The_END________' > debug.h
- X/* /usr/include/stub/debug.h 890123 NHA */
- X/* This is the version for use with public sharing of my sources */
- X/* The intent is to neutralize initdebug() and printd() so that */
- X/* any compiler will swallow them without complaint */
- X/* You may have to tweak this for yours */
- X
- X#ifndef __DEBUG__
- X#define __DEBUG__
- X
- X/** #define printd + **/
- X#define printd
- X#define initdebug(acptr,avptr,confile,lstfile,initstring)
- X
- X#endif __DEBUG__
- ________This_Is_The_END________
- if test `wc -c < debug.h` -ne 436; then
- echo 'shar: debug.h was damaged during transit (should have been 436 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - gen.h'
- if test -f gen.h; then echo 'shar: not overwriting gen.h'; else
- sed 's/^X//' << '________This_Is_The_END________' > gen.h
- X/* /usr/include/stub/gen.h 890123 NHA */
- X/* This is the version for use with public sharing of my sources */
- X/* The intent is to neutralize initdebug() and printd() so that */
- X/* any compiler will swallow them without complaint */
- X
- X#ifndef __GEN__
- X#define __GEN__
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <ctype.h>
- X/** #include "config.h" **/
- X#include <debug.h>
- X
- X#define import extern
- X#define local static
- X#define export
- X/** This will not work with prototypes in version 4.10a **/
- X/** typedef char bool; **/
- Xtypedef int bool;
- X#define NULLFP ((int (*)())0) /* NULL Function Pointer */
- X
- X#define YES 1
- X#define NO 0
- X#define NOBREAK /* used for a switch case which flows into next */
- X#define CRLF 037 /* Unit Separator sometimes replaces \n\r pair */
- X
- X/*** NOTE that this include must follow the definition of bool ***/
- X/** #include <window.h> **/ /* Norman's direct windows */
- X/** import WINDOW *wopen(char *dev); **/
- X
- X/* macros */
- X#define abs(x) ((x < 0) ? (-(x)) : (x))
- X#define max(x,y) (((x) < (y)) ? (y) : (x))
- X#define min(x,y) (((x) < (y)) ? (x) : (y))
- X
- X
- X/* for use with Aztec farcall(), sysint(), and segreg() functions */
- Xstruct regs { int ax, bx, cx, dx, si, di, ds, es; };
- Xstruct segregs { unsigned cs, ss, ds, es; };
- X
- X/* use this to fiddle with longs and pointers and such */
- Xunion u_long {
- X unsigned long lunsigned;
- X long lsigned;
- X void *ptr;
- X struct {
- X unsigned lo;
- X unsigned hi;
- X } half;
- X struct {
- X unsigned char b0; /* Least Significant byte */
- X unsigned char b1;
- X unsigned char b2;
- X unsigned char b3; /* Most Significant byte */
- X } byte;
- X };
- X
- X
- X#define BIT0 0x0001
- X#define BIT1 0x0002
- X#define BIT2 0x0004
- X#define BIT3 0x0008
- X#define BIT4 0x0010
- X#define BIT5 0x0020
- X#define BIT6 0x0040
- X#define BIT7 0x0080
- X#define BIT8 0x0100
- X#define BIT9 0x0200
- X#define BIT10 0x0400
- X#define BIT11 0x0800
- X#define BIT12 0x1000
- X#define BIT13 0x2000
- X#define BIT14 0x4000
- X#define BIT15 0x8000
- X
- X#define BIT0L 0x00000001
- X#define BIT1L 0x00000002
- X#define BIT2L 0x00000004
- X#define BIT3L 0x00000008
- X#define BIT4L 0x00000010
- X#define BIT5L 0x00000020
- X#define BIT6L 0x00000040
- X#define BIT7L 0x00000080
- X#define BIT8L 0x00000100
- X#define BIT9L 0x00000200
- X#define BIT10L 0x00000400
- X#define BIT11L 0x00000800
- X#define BIT12L 0x00001000
- X#define BIT13L 0x00002000
- X#define BIT14L 0x00004000
- X#define BIT15L 0x00008000
- X#define BIT16L 0x00010000
- X#define BIT17L 0x00020000
- X#define BIT18L 0x00040000
- X#define BIT19L 0x00080000
- X#define BIT20L 0x00100000
- X#define BIT21L 0x00200000
- X#define BIT22L 0x00400000
- X#define BIT23L 0x00800000
- X#define BIT24L 0x01000000
- X#define BIT25L 0x02000000
- X#define BIT26L 0x04000000
- X#define BIT27L 0x08000000
- X#define BIT28L 0x10000000
- X#define BIT29L 0x20000000
- X#define BIT30L 0x40000000
- X#define BIT31L 0x80000000
- X
- X#endif __GEN__
- ________This_Is_The_END________
- if test `wc -c < gen.h` -ne 2837; then
- echo 'shar: gen.h was damaged during transit (should have been 2837 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - chksum.c'
- if test -f chksum.c; then echo 'shar: not overwriting chksum.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > chksum.c
- X/* /usr/bin/src/chksum.c 880118 NHA */
- X
- X#define DEBUG 0
- X#define MAJOR 'P'
- X#define MINOR 'C'
- X
- X#include <gen.h>
- X#include <string.h>
- X
- X#define SUCCESS 0
- X#define FAILURE (!SUCCESS)
- X
- X
- X#ifdef __STDC__
- Ximport char *gets(void *buffer);
- Ximport int open(char *filename, int mode);
- Ximport int read(int fd, void *buf, int count);
- Ximport int close(int fd);
- Ximport char *getenv(char *name);
- Ximport void exit(int status);
- Ximport unsigned long crc32buf(unsigned long initialSum,
- X unsigned char *buf, unsigned count);
- X#else
- Ximport char *gets();
- Ximport int open();
- Ximport int read();
- Ximport int close();
- Ximport char *getenv();
- Ximport void exit();
- Ximport unsigned long crc32buf();
- X#endif __STDC__
- X
- Xlocal unsigned char buffer[BUFSIZ]; /* reads go into this buffer */
- Xlocal bool showCount; /* show the byte count [-c] */
- Xlocal bool showError; /* show Errors in any case */
- Xlocal bool totalOnly; /* don't show file sums [-t] */
- Xlocal bool verbose; /* print filenames [-v] */
- Xlocal bool firstFile; /* only true for 1st file */
- Xlocal unsigned fileCount; /* # of files processed OK */
- Xlocal unsigned errorCount; /* # of files with errors */
- Xlocal unsigned long sum; /* checksum for a file */
- Xlocal unsigned long grandSum; /* checksum over all files */
- Xlocal unsigned long byteCount; /* byte count for a file */
- Xlocal unsigned long grandByteCount; /* byte count over all files */
- X
- X
- X
- X
- X/*+ c h k s u m
- X * Calculate two chksums for the file.
- X * One is simply the chksum of the bytes in the file.
- X * The other is updating the grandSum with the bytes in the file.
- X * The grandSum is only updated for files after the first file.
- X * The byteCount and grandByteCount variables are also updated.
- X * Return FAILURE for file errors, else SUCCESS.
- X */
- Xlocal bool chksum(fd)
- Xint fd; /* File Descriptor */
- X {
- X int status; /* status returned from sys calls */
- X
- X printd(4, "chksum(%d)\n", fd);
- X
- X sum = 0L;
- X while (1)
- X {
- X /* read next bufferload from the file */
- X status = read( fd, buffer, sizeof buffer );
- X printd(9, "read status=%d\n", status);
- X if (status < 0)
- X {
- X printd(4, "chksum(): returning FAILURE\n");
- X return FAILURE;
- X }
- X if (status == 0)
- X break; /* End Of File */
- X
- X /* update checksums */
- X sum = crc32buf(sum, buffer, (unsigned)status);
- X if ( ! firstFile )
- X grandSum = crc32buf(grandSum, buffer, (unsigned)status);
- X
- X /* update byte counts */
- X byteCount += (unsigned long)status;
- X grandByteCount += (unsigned long)status;
- X
- X printd(8, "sum=%08lx, grandSum=%08lx, byteCount=%ld, grandByteCount=%ld\n",
- X sum, grandSum, byteCount, grandByteCount);
- X }
- X
- X printd(4, "chksum(): returning SUCCESS with sum=%08lx, grandSum=%08lx\n",
- X sum, grandSum);
- X return SUCCESS;
- X }
- X
- X
- X
- X/*+ s u m F i l e
- X * Given a filename, calculate the checksum, do any necessary displaying,
- X * and update all the necessary global variables.
- X * If the filename is a NULL pointer or a pointer to '\0', we use stdin.
- X * In the event of file access errors, a sum of 0 is printed.
- X */
- Xlocal void sumFile(filename)
- Xchar *filename;
- X {
- X int fd; /* File Descriptor */
- X char name[88];
- X bool isBad; /* YES for file errors */
- X
- X printd(4, "sumFile(%s)\n", filename);
- X byteCount = 0L;
- X
- X /* open input file. NULL or ptr to '\0' is taken to mean standard input */
- X if (filename == NULL || filename[0] == '\0')
- X {
- X strcpy(name, "--Stdin--");
- X fd = fileno(stdin);
- X }
- X else
- X {
- X strcpy(name, filename);
- X fd = open(filename, O_RDONLY);
- X if (fd < 0)
- X {
- X isBad = YES;
- X ++errorCount;
- X sum = 0L;
- X printd(2, "sumFile(%s): can't open file for read\n", filename);
- X if (showError)
- X fprintf(stderr, "chksum: can't open \"%s\" for reading\n",
- X filename);
- X }
- X else
- X isBad = NO;
- X }
- X
- X /* calculate the checksum */
- X if (0 <= fd)
- X {
- X if (chksum(fd) == SUCCESS)
- X {
- X isBad = NO;
- X ++fileCount;
- X if (firstFile)
- X {
- X grandSum = sum;
- X firstFile = NO;
- X }
- X }
- X else
- X {
- X isBad = YES;
- X ++errorCount;
- X sum = 0L;
- X printd(2, "sumFile(%s): error reading file\n", name);
- X if (showError)
- X fprintf(stderr, "chksum: error reading file \"%s\"\n",
- X filename);
- X }
- X if (fd != fileno(stdin))
- X close(fd);
- X }
- X
- X /* report the results */
- X if ( ! totalOnly)
- X {
- X printf("%08lx", sum);
- X if (showCount)
- X printf(" %10lu", byteCount);
- X if (verbose)
- X if (isBad)
- X printf(" %s *** ERROR ***", name);
- X else
- X printf(" %s", name);
- X putchar('\n');
- X }
- X printd(4, "sumFile(): returning\n");
- X }
- X
- X
- X
- X/*+ u s a g e
- X * Spew out the help message.
- X */
- Xlocal void usage()
- X {
- X fprintf(stderr, "chksum -- calculate 32-bit checksum for file(s), output to stdout\n");
- X fprintf(stderr, "Usage: chksum [-cehtv] {file|--|-}...\n");
- X fprintf(stderr, "-c Count bytes also\n");
- X fprintf(stderr, "-e give extended Error reports on stderr\n");
- X fprintf(stderr, "-h Help; give this help message and exit\n");
- X fprintf(stderr, "-t Total only; don't list sum for each file\n");
- X fprintf(stderr, "-v Verbose; list filenames along with checksums\n");
- X fprintf(stderr, "-- take filenames from stdin, 1 name per line\n");
- X fprintf(stderr, "- take stdin as a file\n");
- X fprintf(stderr, "Filenames may be mixed with options.\n");
- X fprintf(stderr, "Exit status is the number of file errors encountered.\n");
- X exit(1);
- X } /* usage */
- X
- X
- X
- X/*+ m a i n
- X * See usage() for command line parameters.
- X */
- Xexport int main(ac, av)
- Xint ac;
- Xchar **av;
- X {
- X char *p;
- X char line[BUFSIZ]; /* for reading from stdin */
- X char switchar;
- X
- X /* initialize */
- X initdebug(&ac, &av, "/dev/con", "/dev/fifo", "**0");
- X showCount = NO; /* default is no byte counts */
- X showError = NO; /* default is no reports on stderr*/
- X totalOnly = NO; /* default is show all checksums */
- X verbose = NO; /* default is no filenames */
- X firstFile = YES; /* no files checksummed yet */
- X fileCount = 0;
- X errorCount = 0;
- X grandSum = 0L;
- X grandByteCount = 0L;
- X p = getenv("SWITCHAR");
- X if (p == NULL)
- X switchar = '-';
- X else
- X switchar = *p;
- X
- X /* process command line arguments */
- X for (--ac, ++av ; 0 < ac ; --ac, ++av)
- X {
- X printd(7, "main(): ac = %d, *av = '%s'\n", ac, *av);
- X if (av[0][0] == switchar)
- X switch (av[0][1])
- X {
- X case 'C':
- X case 'c':
- X showCount = YES;
- X break;
- X case 'E':
- X case 'e':
- X showError = YES;
- X break;
- X case 'H':
- X case 'h':
- X usage();
- X break;
- X case 'T':
- X case 't':
- X totalOnly = YES;
- X break;
- X case 'V':
- X case 'v':
- X verbose = YES;
- X break;
- X case '-': /* take filenames from stdin */
- X while (gets(line) != NULL)
- X sumFile(line);
- X if (showError && ferror(stdin))
- X fprintf(stderr, "chksum: error reading standard input\n");
- X clearerr(stdin);
- X break;
- X case '\0':
- X sumFile(NULL); /* use standard input for file */
- X break;
- X default:
- X fprintf(stderr, "chksum: unknown option %s\n", av[0]);
- X } /* switch */
- X else
- X sumFile(av[0]); /* file */
- X }
- X
- X
- X /* put out the Grand Total */
- X if ((fileCount + errorCount) == 0)
- X usage(); /* no files specified */
- X else if ((fileCount + errorCount) == 1)
- X { /* one file specified */
- X if (totalOnly)
- X {
- X printf("%08lx", grandSum);
- X if (showCount)
- X printf(" %10lu", grandByteCount);
- X putchar('\n');
- X }
- X }
- X else
- X { /* multiple files specified */
- X if ( ! totalOnly)
- X {
- X printf("========");
- X if (showCount)
- X printf("============");
- X putchar('\n');
- X }
- X printf("%08lx", grandSum);
- X if (showCount)
- X printf(" %10lu", grandByteCount);
- X if (verbose)
- X {
- X if (showCount)
- X printf(" Grand Totals for %u files", fileCount);
- X else
- X printf(" Grand Total for %u files", fileCount);
- X if (errorCount == 1)
- X printf(" ***** plus 1 ERROR *****");
- X else if (1 < errorCount)
- X printf(" ***** plus %u ERRORS *****", errorCount);
- X }
- X putchar('\n');
- X }
- X printd(3, "chksum: returning %u", errorCount);
- X exit(errorCount);
- X } /* main */
- ________This_Is_The_END________
- if test `wc -c < chksum.c` -ne 8136; then
- echo 'shar: chksum.c was damaged during transit (should have been 8136 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - crc32.c'
- if test -f crc32.c; then echo 'shar: not overwriting crc32.c'; else
- sed 's/^X//' << '________This_Is_The_END________' > crc32.c
- X/* /usr/lib/src/pd/crc32.c 881102 NHA */
- X/*
- X * Crc - 32 BIT ANSI X3.66 CRC checksum files
- X */
- X
- X#define TEST 0
- X#define DEBUG 0
- X#define FAST 0
- X
- X#define MAJOR 'L'
- X#define MINOR 'C'
- X
- X#include <gen.h>
- X
- X#define OK 0
- X#define ERROR (-1)
- X#define LINT_ARGS
- X
- X/**********************************************************************\
- X|* *|
- X|* Demonstration program to compute the 32-bit CRC used as the frame *|
- X|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
- X|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
- X|* protocol). The 32-bit FCS was added via the Federal Register, *|
- X|* 1 June 1982, p.23798. I presume but don't know for certain that *|
- X|* this polynomial is or will be included in CCITT V.41, which *|
- X|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
- X|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
- X|* errors by a factor of 10^-5 over 16-bit FCS. *|
- X|* *|
- X\**********************************************************************/
- X
- X/* Need an unsigned type capable of holding 32 bits; */
- Xtypedef unsigned long int UNS_32_BITS;
- X
- X/*
- X * Copyright (C) 1986 Gary S. Brown. You may use this program, or
- X * code or tables extracted from it, as desired without restriction.
- X */
- X/* First, the polynomial itself and its table of feedback terms. The */
- X/* polynomial is */
- X/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
- X/* Note that we take it "backwards" and put the highest-order term in */
- X/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
- X/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
- X/* the MSB being 1. */
- X
- X/* Note that the usual hardware shift register implementation, which */
- X/* is what we're using (we're merely optimizing it by doing eight-bit */
- X/* chunks at a time) shifts bits into the lowest-order term. In our */
- X/* implementation, that means shifting towards the right. Why do we */
- X/* do it this way? Because the calculated CRC must be transmitted in */
- X/* order from highest-order term to lowest-order term. UARTs transmit */
- X/* characters in order from LSB to MSB. By storing the CRC this way, */
- X/* we hand it to the UART in the order low-byte to high-byte; the UART */
- X/* sends each low-bit to hight-bit; and the result is transmission bit */
- X/* by bit from highest- to lowest-order term without requiring any bit */
- X/* shuffling on our part. Reception works similarly. */
- X
- X/* The feedback terms table consists of 256, 32-bit entries. Notes: */
- X/* */
- X/* 1. The table can be generated at runtime if desired; code to do so */
- X/* is shown later. It might not be obvious, but the feedback */
- X/* terms simply represent the results of eight shift/xor opera- */
- X/* tions for all combinations of data and CRC register values. */
- X/* */
- X/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
- X/* be they sixteen or thirty-two bits wide. You simply choose the */
- X/* appropriate table. Alternatively, because the table can be */
- X/* generated at runtime, you can start by generating the table for */
- X/* the polynomial in question and use exactly the same "updcrc", */
- X/* if your application needn't simultaneously handle two CRC */
- X/* polynomials. (Note, however, that XMODEM is strange.) */
- X/* */
- X/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
- X/* of course, 32-bit entries work OK if the high 16 bits are zero. */
- X/* */
- X/* 4. The values must be right-shifted by eight bits by the "updcrc" */
- X/* logic; the shift must be unsigned (bring in zeroes). On some */
- X/* hardware you could probably optimize the shift in assembler by */
- X/* using byte-swap instructions. */
- X
- Xstatic UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
- X0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- X0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- X0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- X0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- X0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- X0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- X0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- X0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- X0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- X0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- X0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- X0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- X0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- X0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- X0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- X0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- X0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- X0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- X0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- X0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- X0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- X0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- X0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- X0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- X0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- X0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- X0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- X0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- X0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- X0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- X0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- X0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- X0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- X0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- X0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- X0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- X0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- X0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- X0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- X0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- X0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- X0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- X0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- X0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- X0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- X0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- X0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- X0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- X0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- X0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- X0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- X0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- X0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- X0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- X0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- X0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- X0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- X0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- X0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- X0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- X0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- X0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- X0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- X0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
- X};
- X
- X
- X
- X/*+ c r c 3 2 b u f
- X * Given an initial 32-bit CRC and a buffer, calculate the new CRC.
- X * Returns the new CRC.
- X */
- Xexport UNS_32_BITS crc32buf( crc, cp, cnt )
- XUNS_32_BITS crc; /* initial CRC */
- Xunsigned char *cp; /* pointer to buffer */
- Xunsigned cnt; /* # chars in buffer */
- X {
- X printd(3, "crc32buf(%lu, %p, %u)\n", crc, cp, cnt);
- X
- X#if FAST
- X#asm
- X;es:si holds pointer to buffer (cp)
- X;cx holds count (cnt)
- X;dx,ax holds crc hi,lo
- X mov cx, word ptr 14[bp] ;cnt
- X jcxz done
- X mov ax, word ptr 6[bp] ;crc lo
- X mov dx, word ptr 8[bp] ;crc hi
- X les bx, dword ptr 10[bp] ;cp
- X mov si, bx
- Xagain:
- X mov bl, es:byte ptr [si] ;octet
- X xor bl, al ;crc ^ octet & 0377
- X xor bh, bh
- X shl bx, 1
- X shl bx, 1 ;bx is index into crc_32_tab
- X mov al, ah ;crc >>= 8
- X mov ah, dl
- X mov dl, dh
- X xor dh, dh
- X xor ax, word ptr crc_32_tab_[bx] ;low word
- X xor dx, word ptr crc_32_tab_[bx+2] ;high word
- X inc si
- X loop again
- X mov word ptr 6[bp], ax ;crc lo
- X mov word ptr 8[bp], dx ;crc hi
- Xdone:
- X#endasm
- X#else FAST
- X#define W 16
- X#define B 8
- X while( cnt-- ) {
- X# if SWAPPED
- X crc = (crc<<B) ^ crc_32_tab[(crc>>(W-B)) ^ *cp++];
- X# else SWAPPED
- X crc = (crc>>B) ^ crc_32_tab[(crc & ((1<<B)-1)) ^ *cp++];
- X# endif SWAPPED
- X printd(8, "crc32buf(): cnt=%u, crc=%08lx\n", cnt, crc);
- X }
- X#endif FAST
- X
- X printd(3, "crc32buf(): returning %lu\n", crc);
- X return( crc );
- X} /* crc32buf() */
- X
- X
- X
- X/*+ c r c 3 2 1
- X * Given a 32-bit CRC and a byte, return the new CRC which includes the byte.
- X */
- Xexport UNS_32_BITS crc321( crc, octet )
- XUNS_32_BITS crc;
- Xunsigned char octet;
- X {
- X UNS_32_BITS newcrc;
- X printd(3, "crc321(%lu, %#02x)\n", crc, octet);
- X#if FAST
- X#asm
- X mov bl, byte ptr 10[bp] ;octet
- X xor bl, byte ptr 6[bp] ;(crc ^ octet) & 0377
- X xor bh, bh
- X shl bx, 1
- X shl bx, 1 ;bx is index into crc_32_tab
- X mov ax, word ptr crc_32_tab_[bx] ;low word
- X mov dx, word ptr crc_32_tab_[bx+2] ;high word
- X xor ax, word ptr 7[bp] ;xor with (crc >> 8), low word
- X xor dl, byte ptr 9[bp] ;xor with (crc >> 8), high byte
- X mov word ptr -4[bp], ax ;store in newcrc
- X mov word ptr -2[bp], dx ; for printf() and return value
- X#endasm
- X#else FAST
- X newcrc = (crc_32_tab[((crc) ^ (octet)) & 0377] ^ ((crc) >> 8));
- X#endif FAST
- X printd(3, "crc321(): returning %lu\n", newcrc);
- X return newcrc;
- X} /* crc321() */
- X
- X
- X#if TEST
- X
- X#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
- X
- X
- Xlocal crc32file(name)
- Xchar *name;
- X{
- X register FILE *fin;
- X register unsigned long oldcrc32;
- X register unsigned long crc32;
- X register unsigned long oldcrc;
- X register c;
- X register long charcnt;
- X
- X oldcrc32 = 0xFFFFFFFF; charcnt = 0;
- X#ifdef M_I86SM
- X if ((fin=fopen(name, "rb"))==NULL)
- X#else
- X if ((fin=fopen(name, "r"))==NULL)
- X#endif
- X {
- X perror(name);
- X return ERROR;
- X }
- X while ((c=getc(fin))!=EOF) {
- X ++charcnt;
- X/** oldcrc32 = UPDC32(c, oldcrc32); **/
- X oldcrc32 = crc321(oldcrc32, c);
- X }
- X
- X if (ferror(fin)) {
- X perror(name);
- X charcnt = -1;
- X }
- X fclose(fin);
- X
- X crc32 = oldcrc32; oldcrc = oldcrc32 = ~oldcrc32;
- X
- X/*
- X crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8;
- X crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8;
- X crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8;
- X crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8;
- X printf("%08lX ", crc32);
- X*/
- X
- X printf("%08lX %7ld %s\n", oldcrc, charcnt, name);
- X
- X return OK;
- X}
- X
- X
- Xexport main(argc, argp)
- Xchar **argp;
- X{
- X register errors = 0;
- X
- X while( --argc > 0)
- X errors |= crc32file( *++argp);
- X exit(errors != 0);
- X}
- X#endif TEST
- ________This_Is_The_END________
- if test `wc -c < crc32.c` -ne 11016; then
- echo 'shar: crc32.c was damaged during transit (should have been 11016 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-
-
-