source: gsdl/trunk/packages/isis-gdl/CRC32.cpp@ 14171

Last change on this file since 14171 was 6189, checked in by jrm21, 20 years ago

fixes so it compiles with gcc 3 as well as gcc 2.9x

  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/**********************************************************************
2 *
3 * CRC32.cpp
4 * Copyright (C) 2003 UNESCO
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26////////////////////////////////////////////////////////////////////////////////////
27// CRC32.cpp --
28//
29// The CRC32 functions (Cyclic Redundancy Check) are used to
30// calculate a sophisticated checksum based on the algebra of
31// polynomials. The Cyclic Redundancy Check, is a way to detect
32// bit errors that occur during data storage or transmission.
33// The CRC-32 algorithm operates on a block of data as a single
34// large numerical value. The algorithm divides this large value
35// by the CRC-32 polynomial or generator polynomial, leaving the
36// remainder 32-bit, which is the checksum.
37//
38// #include "stdafx.h"
39#include <iomanip>
40#include "CRC32.h"
41#include "CRCTab.h"
42
43unsigned long CalcCRC32(const char *buf, unsigned len)
44// Calculate a 32-bit CRC for a raw pattern of bytes.
45// Returns a 32-bit checksum.
46{
47 unsigned long CRC=0xffffffffL;
48 unsigned int n = len;
49
50 while(n--)
51 CRC=crc32tab[(CRC ^ (*buf++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
52
53 return CRC ^ 0xffffffffL;
54}
55
56unsigned long CalcCRC32(char *buf, unsigned len)
57// Calculate a 32-bit CRC for a raw pattern of bytes.
58// Returns a 32-bit checksum.
59{
60 unsigned long CRC=0xffffffffL;
61 unsigned int n = len;
62 char *p = (char *)buf;
63 while(n--)
64 CRC=crc32tab[(CRC ^ (*p++)) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
65
66 return CRC ^ 0xffffffffL;
67}
68
69unsigned long CalcCRC32(unsigned char c, unsigned long CRC)
70// Calculate a 32-bit CRC table value for a single byte.
71// NOTE: The initial CRC value must be set to 0xffffffffL
72// and the final 32-bit value that must be XOR'ed with
73// 0xffffffffL to obtain the checksum.
74{
75 unsigned int i;
76 i = (unsigned int)c;
77 i &= 0xFF; // Reset all the bits
78 CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
79 return CRC;
80}
81
82unsigned long CalcCRC32(std::fstream &infile)
83// Calculate a 32-bit CRC for a file. Assumes the stream
84// is already open. Returns a 32-bit checksum.
85{
86 unsigned long CRC=0xffffffffL;
87#ifdef _WIN32
88 char c;
89#else
90 unsigned char c;
91#endif
92 unsigned int i;
93
94 // Rewind to the start of the stream
95 infile.clear();
96 infile.seekg(0, std::ios::beg);
97 infile.seekp(0, std::ios::beg);
98
99 while(!infile.eof()) {
100 c=infile.get();
101 i = (unsigned int)c;
102 i &= 0xFF; // Reset all the bits
103 if(infile.eof()) break;
104 CRC=crc32tab[(CRC ^ i) & 0xFF] ^ ((CRC>>8) & 0x00ffffffL);
105 }
106 return CRC ^ 0xffffffffL;
107}
108
109#ifdef __USE_CRC32_TABLE_FUNCTIONS__
110int MakeCRC32(ostream &stream)
111// Write a CRC 32 table for a byte-wise 32-bit CRC calculation
112// based on the Autodin/Ethernet/ADCCP polynomial of 0x4C11DB7:
113// 0000 0100 1100 0001 0001 1101 1011 0111 (binary) or a poly of
114// 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
115// In this representation the coefficient of x^0 is stored in the
116// MSB of the 32-bit word and the coefficient of x^31 is stored in
117// the LSB. Thus 0x4C11DB7 becomes 0xEDB88320:
118// 1110 1101 1011 1000 1000 0011 0010 0000 (binary)
119
120// Adding the polynomials is performed using an exclusive-or, and
121// multiplying a polynomial by x is a right shift by one. If the
122// polynomial is called "p", and each byte is represented as polynomial
123// "q", with the lowest power in the most significant bit (so the byte
124// 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32)
125// mod "p", where "a" mod "b" means the remainder after dividing "a" by
126// "b". This calculation is done using the shift-register method of
127// multiplying and taking the remainder. The register is initialized
128// to zero, and for each incoming bit, x^32 is added mod "p" to the
129// register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1),
130// and the register is multiplied mod "p" by "x" (which is shifting right
131// by one and adding x^32 mod "p" if the bit shifted out is a one.) This
132// algorithm starts with the highest power (least significant bit) of "q"
133// and repeats for all eight bits of "q".
134{
135 unsigned long c; // CRC shift register
136 unsigned long e; // Polynomial exclusive-or pattern
137 int i; // Counter for all possible eight bit values
138 int k; // Byte being shifted into crc apparatus
139
140 // Terms of polynomial defining this crc (except x^32):
141 static const int p[14] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
142
143 // Make exclusive-or pattern from polynomial
144 e = 0;
145 for (i = 0; i < sizeof(p)/sizeof(int); i++)
146 e |= 1L << (31 - p[i]);
147
148 // Compute and print table of CRC's, five per line
149 stream << endl;
150 stream << " 0x00000000U";
151 for (i = 1; i < 256; i++)
152 {
153 c = 0;
154 for (k = i | 256; k != 1; k >>= 1)
155 {
156 c = c & 1 ? (c >> 1) ^ e : c >> 1;
157 if (k & 1)
158 c ^= e;
159 }
160
161 if(i % 5)
162 stream << ", 0x" << setfill('0') << setw(8) << hex << c << "U";
163 else
164 stream << "," << endl << " 0x" << setfill('0') << setw(8) << hex
165 << c << "U";
166 }
167 stream << endl;
168 return 1;
169}
170#endif // __USE_CRC32_TABLE_FUNCTIONS__
Note: See TracBrowser for help on using the repository browser.