djj@machaids.UUCP (Don) (11/09/83)
About a month ago I put a request for CRC (Cyclic Redundancy Codes) information on this net. I received in a number of good programs and comments, and several requests to forward whatever I discovered. Since I have not been able send mail to several of the people who made requests, I'll put this summary on the net. It appears that CRC calculations are based on a polynomial that is not standardized, so it is possible to have several different valid CRC values for the same file simply by using different polynomials. There is an article in the June 83 issue of IEEE Micro which gives a little background on CRC and on a method for calculating same. Unfortunately, the examples are given in assembler. One of the C programs I received, and modified slightly produces CRC values identical to those produced by CRCK.COM and "uc" the UNIX/CPM communications program that is intended to replace "umodem". Here is the source code ---- "crck.c" (118 lines; 493 words; 2874 bytes): /* * ---- crck.c ---- * * Version 1.0 - 4/9/83 * * This UN*X program performs a file hashsum calculation consistent * with the de facto standard (but misnamed) "CRCK" program for CP/M. * * Usage: crck [-w] filename... * * The -w flag suppresses the warning message that normally * is printed when a file is found not to be a multiple of * 128 bytes in size. (Such a file cannot be a faithful copy * of a CP/M file, since CP/M files are always a multiple of * 128 bytes). * * Notes: * 1. Two versions of the CRCK program exist in the CP/M * world. Variants of Keith Petersen's original program * are the de facto standard, even though they misuse the * underlying CRC calculation subroutine and therefore don't * really perform a "CRC" function. This program produces * hashsums consistent with Petersen's scheme, currently * found in the "CRCK4x.ASM" series. * * 2. In order for valid comparisons to be made between the * CP/M and UNIX copies of a file, the file must, of course, * have been transferred intact; i.e., with the "-rb" option * of umodem, or the "-b" option of rb. * * Jeff Martin * Naperville, Il. * 4/9/83 * Version 1.1 -- djj Oct 13, 1983 * Changed output print format, to make it more readable! * Don Jackowski, Mine Hill, NJ */ #include <stdio.h> #include <fcntl.h> #define CPMSEC 128 main(argc, argv) int argc; char *argv[]; { int c, fdi, warn, wflg; char *s, *in_file; char cbuf[CPMSEC]; unsigned crc, crck(); warn = 1; while (--argc > 0 && (*++argv)[0] == '-') { for (s = argv[0]+1; *s != '\0'; s++) { switch (*s) { case 'w': warn = 0; break; default: printf("illegal option: '%c'\n", *s); argc = 0; break; } } } if (argc < 1) { printf("Usage: crck [-w] filename...\n"); exit(1); } while (argc-- > 0) { in_file = (argv++)[0]; fdi = open(in_file, O_RDONLY); if (fdi < 0) { printf("Cannot access %s\n", in_file); continue; } crc = wflg = 0; while ((c = read(fdi, cbuf, CPMSEC)) > 0) { if ((c != CPMSEC) && warn) { wflg++; } crc = crck(cbuf, c, crc); } printf("%14s --> %04X", in_file, crc); if(wflg)printf(" <-- not CP/M sector sized.\n"); else printf("\n"); close(fdi); continue; } } /* * The only good thing to be said about the following function is that * it faithfully emulates the 8080 code in the CRCK4x.ASM series. It * does NOT perform a CRC calculation, but does a rather bizarre hash * sum. */ unsigned crck(buf, size, oldcrc) char *buf; int size; unsigned oldcrc; { register unsigned newcrc, tmp; register int i, qbit; newcrc = oldcrc; for (i = 0; i < size; i++) { qbit = newcrc & 0x8000; newcrc <<= 1; tmp = (newcrc + *buf++) & 0xff; newcrc = (newcrc & 0xff00) | tmp; if (qbit) { newcrc ^= 0xA097; } } return (newcrc); }