home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: crc32.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 08/17/1998
- // Date Last Modified: 03/15/1999
- // ----------------------------------------------------------- //
- // ------------- Program description and details ------------- //
- // ----------------------------------------------------------- //
- /*
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- The CRC32 functions (Cyclic Redundancy Check) are used to
- calculate a sophisticated checksum based on the algebra of
- polynomials. The Cyclic Redundancy Check, is a way to detect
- bit errors that occur during data storage or transmission.
- The CRC-32 algorithm operates on a block of data as a single
- large numerical value. The algorithm divides this large value
- by the CRC-32 polynomial or generator polynomial, leaving the
- remainder 32-bit, which is the checksum.
- */
- // ----------------------------------------------------------- //
- #include <iomanip.h>
- #include "crc32.h"
- #include "crc32tab.h"
-
- unsigned long calcCRC32(const char *buf, unsigned len)
- // Calculate a 32-bit CRC for a raw pattern of bytes.
- // Returns a 32-bit checksum.
- {
- unsigned long CRC=0xffffffffL;
- unsigned int n = len;
-
- while(n--)
- CRC=crc32tab[(CRC ^ (*buf++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
-
- return CRC ^ 0xffffffffL;
- }
-
- unsigned long calcCRC32(char *buf, unsigned len)
- // Calculate a 32-bit CRC for a raw pattern of bytes.
- // Returns a 32-bit checksum.
- {
- unsigned long CRC=0xffffffffL;
- unsigned int n = len;
- char *p = (char *)buf;
- while(n--)
- CRC=crc32tab[(CRC ^ (*p++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
-
- return CRC ^ 0xffffffffL;
- }
-
- unsigned long calcCRC32(unsigned char c, unsigned long CRC)
- // Calculate a 32-bit CRC table value for a single byte.
- // NOTE: The initial CRC value must be set to 0xffffffffL
- // and the final 32-bit value that must be XOR'ed with
- // 0xffffffffL to obtain the checksum.
- {
- unsigned int i;
- i = (unsigned int)c;
- i &= 0xFF; // Reset all the bits
- CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
- return CRC;
- }
-
- unsigned long calcCRC32(fstream &infile)
- // Calculate a 32-bit CRC for a file. Assumes the stream
- // is already open. Returns a 32-bit checksum.
- {
- unsigned long CRC=0xffffffffL;
- unsigned char c;
- unsigned int i;
-
- // Rewind to the start of the stream
- infile.clear();
- infile.seekg(0, ios::beg);
- infile.seekp(0, ios::beg);
-
- while(!infile.eof()) {
- infile.get(c);
- i = (unsigned int)c;
- i &= 0xFF; // Reset all the bits
- if(infile.eof()) break;
- CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
- }
- return CRC ^ 0xffffffffL;
- }
-
- int makeCRC32(ostream &stream)
- // Write a CRC 32 table for a byte-wise 32-bit CRC calculation
- // based on the Autodin/Ethernet/ADCCP polynomial of 0x4C11DB7:
- // 0000 0100 1100 0001 0001 1101 1011 0111 (binary) or a poly of
- // 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
- // In this representation the coefficient of x^0 is stored in the
- // MSB of the 32-bit word and the coefficient of x^31 is stored in
- // the LSB. Thus 0x4C11DB7 becomes 0xEDB88320:
- // 1110 1101 1011 1000 1000 0011 0010 0000 (binary)
-
- // Adding the polynomials is performed using an exclusive-or, and
- // multiplying a polynomial by x is a right shift by one. If the
- // polynomial is called "p", and each byte is represented as polynomial
- // "q", with the lowest power in the most significant bit (so the byte
- // 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32)
- // mod "p", where "a" mod "b" means the remainder after dividing "a" by
- // "b". This calculation is done using the shift-register method of
- // multiplying and taking the remainder. The register is initialized
- // to zero, and for each incoming bit, x^32 is added mod "p" to the
- // register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1),
- // and the register is multiplied mod "p" by "x" (which is shifting right
- // by one and adding x^32 mod "p" if the bit shifted out is a one.) This
- // algorithm starts with the highest power (least significant bit) of "q"
- // and repeats for all eight bits of "q".
- {
- unsigned long c; // CRC shift register
- unsigned long e; // Polynomial exclusive-or pattern
- int i; // Counter for all possible eight bit values
- int k; // Byte being shifted into crc apparatus
-
- // Terms of polynomial defining this crc (except x^32):
- static const int p[14] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- // Make exclusive-or pattern from polynomial
- e = 0;
- for (i = 0; i < sizeof(p)/sizeof(int); i++)
- e |= 1L << (31 - p[i]);
-
- // Compute and print table of CRC's, five per line
- stream << endl;
- stream << " 0x00000000U";
- for (i = 1; i < 256; i++)
- {
- c = 0;
- for (k = i | 256; k != 1; k >>= 1)
- {
- c = c & 1 ? (c >> 1) ^ e : c >> 1;
- if (k & 1)
- c ^= e;
- }
-
- if(i % 5)
- stream << ", 0x" << setfill('0') << setw(8) << hex << c << "U";
- else
- stream << "," << endl << " 0x" << setfill('0') << setw(8) << hex
- << c << "U";
- }
- stream << endl;
- return 1;
- }
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-