ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
crc32.c
Go to the documentation of this file.
1/* crc32.c -- compute the CRC-32 of a data stream
2 * Copyright (C) 1995-2006, 2010 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 *
5 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
6 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
7 * tables for updating the shift register in one step with three exclusive-ors
8 * instead of four steps with four exclusive-ors. This results in about a
9 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
10 */
11
12/* @(#) $Id$ */
13
14/*
15 Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
16 protection on the static variables used to control the first-use generation
17 of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
18 first call get_crc_table() to initialize the tables before allowing more than
19 one thread to use crc32().
20 */
21
22#ifdef MAKECRCH
23# include <stdio.h>
24# ifndef DYNAMIC_CRC_TABLE
25# define DYNAMIC_CRC_TABLE
26# endif /* !DYNAMIC_CRC_TABLE */
27#endif /* MAKECRCH */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
33
34#include "zutil.h" /* for STDC and FAR definitions */
35
37
38#define local static
39
40/* Find a four-byte integer type for crc32_little() and crc32_big(). */
41#ifndef NOBYFOUR
42# ifdef STDC /* need ANSI C limits.h to determine sizes */
44# include <limits.h>
46# define BYFOUR
47# if (UINT_MAX == 0xffffffffUL)
48 typedef unsigned int u4;
49# else
50# if (ULONG_MAX == 0xffffffffUL)
51 typedef unsigned long u4;
52# else
53# if (USHRT_MAX == 0xffffffffUL)
54 typedef unsigned short u4;
55# else
56# undef BYFOUR /* can't find a four-byte integer type! */
57# endif
58# endif
59# endif
60# endif /* STDC */
61#endif /* !NOBYFOUR */
62
63/* Definitions for doing the crc four data bytes at a time. */
64#ifdef BYFOUR
65# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
66 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
67 local unsigned long crc32_little OF((unsigned long,
68 const unsigned char FAR *, unsigned));
69 local unsigned long crc32_big OF((unsigned long,
70 const unsigned char FAR *, unsigned));
71# define TBLS 8
72#else
73# define TBLS 1
74#endif /* BYFOUR */
75
76/* Local functions for crc concatenation */
77local unsigned long gf2_matrix_times OF((unsigned long *mat,
78 unsigned long vec));
79local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
81
82
83#ifdef DYNAMIC_CRC_TABLE
84
85local volatile int crc_table_empty = 1;
86local unsigned long FAR crc_table[TBLS][256];
87local void make_crc_table OF((void));
88#ifdef MAKECRCH
89 local void write_table OF((FILE *, const unsigned long FAR *));
90#endif /* MAKECRCH */
91/*
92 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
93 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.
94
95 Polynomials over GF(2) are represented in binary, one bit per coefficient,
96 with the lowest powers in the most significant bit. Then adding polynomials
97 is just exclusive-or, and multiplying a polynomial by x is a right shift by
98 one. If we call the above polynomial p, and represent a byte as the
99 polynomial q, also with the lowest power in the most significant bit (so the
100 byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
101 where a mod b means the remainder after dividing a by b.
102
103 This calculation is done using the shift-register method of multiplying and
104 taking the remainder. The register is initialized to zero, and for each
105 incoming bit, x^32 is added mod p to the register if the bit is a one (where
106 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
107 x (which is shifting right by one and adding x^32 mod p if the bit shifted
108 out is a one). We start with the highest power (least significant bit) of
109 q and repeat for all eight bits of q.
110
111 The first table is simply the CRC of all possible eight bit values. This is
112 all the information needed to generate CRCs on data a byte at a time for all
113 combinations of CRC register values and incoming bytes. The remaining tables
114 allow for word-at-a-time CRC calculation for both big-endian and little-
115 endian machines, where a word is four bytes.
116*/
117local void make_crc_table()
118{
119 unsigned long c;
120 int n, k;
121 unsigned long poly; /* polynomial exclusive-or pattern */
122 /* terms of polynomial defining this crc (except x^32): */
123 static volatile int first = 1; /* flag to limit concurrent making */
124 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
125
126 /* See if another task is already doing this (not thread-safe, but better
127 than nothing -- significantly reduces duration of vulnerability in
128 case the advice about DYNAMIC_CRC_TABLE is ignored) */
129 if (first) {
130 first = 0;
131
132 /* make exclusive-or pattern from polynomial (0xedb88320UL) */
133 poly = 0UL;
134 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
135 poly |= 1UL << (31 - p[n]);
136
137 /* generate a crc for every 8-bit value */
138 for (n = 0; n < 256; n++) {
139 c = (unsigned long)n;
140 for (k = 0; k < 8; k++)
141 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
142 crc_table[0][n] = c;
143 }
144
145#ifdef BYFOUR
146 /* generate crc for each value followed by one, two, and three zeros,
147 and then the byte reversal of those as well as the first table */
148 for (n = 0; n < 256; n++) {
149 c = crc_table[0][n];
150 crc_table[4][n] = REV(c);
151 for (k = 1; k < 4; k++) {
152 c = crc_table[0][c & 0xff] ^ (c >> 8);
153 crc_table[k][n] = c;
154 crc_table[k + 4][n] = REV(c);
155 }
156 }
157#endif /* BYFOUR */
158
159 crc_table_empty = 0;
160 }
161 else { /* not first */
162 /* wait for the other guy to finish (not efficient, but rare) */
163 while (crc_table_empty)
164 ;
165 }
166
167#ifdef MAKECRCH
168 /* write out CRC tables to crc32.h */
169 {
170 FILE *out;
171
172 out = fopen("crc32.h", "w");
173 if (out == NULL) return;
174 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
175 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
176 fprintf(out, "local const unsigned long FAR ");
177 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
178 write_table(out, crc_table[0]);
179# ifdef BYFOUR
180 fprintf(out, "#ifdef BYFOUR\n");
181 for (k = 1; k < 8; k++) {
182 fprintf(out, " },\n {\n");
183 write_table(out, crc_table[k]);
184 }
185 fprintf(out, "#endif\n");
186# endif /* BYFOUR */
187 fprintf(out, " }\n};\n");
188 fclose(out);
189 }
190#endif /* MAKECRCH */
191}
192
193#ifdef MAKECRCH
194local void write_table(FILE *out, const unsigned long FAR *table)
195{
196 int n;
197
198 for (n = 0; n < 256; n++)
199 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
200 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
201}
202#endif /* MAKECRCH */
203
204#else /* !DYNAMIC_CRC_TABLE */
205/* ========================================================================
206 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
207 */
209#include "crc32.h"
211#endif /* DYNAMIC_CRC_TABLE */
212
213/* =========================================================================
214 * This function can be used by asm versions of crc32()
215 */
216const unsigned long FAR * ZEXPORT get_crc_table()
217{
218#ifdef DYNAMIC_CRC_TABLE
219 if (crc_table_empty)
220 make_crc_table();
221#endif /* DYNAMIC_CRC_TABLE */
222 return (const unsigned long FAR *)crc_table;
223}
224
225/* ========================================================================= */
226#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
227#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
228
229/* ========================================================================= */
230unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
231{
232 if (buf == Z_NULL) return 0UL;
233
234#ifdef DYNAMIC_CRC_TABLE
235 if (crc_table_empty)
236 make_crc_table();
237#endif /* DYNAMIC_CRC_TABLE */
238
239#ifdef BYFOUR
240 if (sizeof(void *) == sizeof(ptrdiff_t)) {
241 u4 endian;
242
243 endian = 1;
244 if (*((unsigned char *)(&endian)))
245 return crc32_little(crc, buf, len);
246 else
247 return crc32_big(crc, buf, len);
248 }
249#endif /* BYFOUR */
250 crc = crc ^ 0xffffffffUL;
251 while (len >= 8) {
252 DO8;
253 len -= 8;
254 }
255 if (len) do {
256 DO1;
257 } while (--len);
258 return crc ^ 0xffffffffUL;
259}
260
261#ifdef BYFOUR
262
263/* ========================================================================= */
264#define DOLIT4 c ^= *buf4++; \
265 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
266 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
267#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
268
269/* ========================================================================= */
270local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len)
271{
272 u4 c;
273 const u4 FAR *buf4;
274
275 c = (u4)crc;
276 c = ~c;
277 while (len && ((ptrdiff_t)buf & 3)) {
278 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
279 len--;
280 }
281
282 buf4 = (const u4 FAR *)(const void FAR *)buf;
283 while (len >= 32) {
284 DOLIT32;
285 len -= 32;
286 }
287 while (len >= 4) {
288 DOLIT4;
289 len -= 4;
290 }
291 buf = (const unsigned char FAR *)buf4;
292
293 if (len) do {
294 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
295 } while (--len);
296 c = ~c;
297 return (unsigned long)c;
298}
299
300/* ========================================================================= */
301#define DOBIG4 c ^= *++buf4; \
302 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
303 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
304#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
305
306/* ========================================================================= */
307local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, unsigned len)
308{
309 u4 c;
310 const u4 FAR *buf4;
311
312 c = REV((u4)crc);
313 c = ~c;
314 while (len && ((ptrdiff_t)buf & 3)) {
315 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
316 len--;
317 }
318
319 buf4 = (const u4 FAR *)(const void FAR *)buf;
320 buf4--;
321 while (len >= 32) {
322 DOBIG32;
323 len -= 32;
324 }
325 while (len >= 4) {
326 DOBIG4;
327 len -= 4;
328 }
329 buf4++;
330 buf = (const unsigned char FAR *)buf4;
331
332 if (len) do {
333 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
334 } while (--len);
335 c = ~c;
336 return (unsigned long)(REV(c));
337}
338
339#endif /* BYFOUR */
340
341#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
342
343/* ========================================================================= */
344local unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec)
345{
346 unsigned long sum;
347
348 sum = 0;
349 while (vec) {
350 if (vec & 1)
351 sum ^= *mat;
352 vec >>= 1;
353 mat++;
354 }
355 return sum;
356}
357
358/* ========================================================================= */
359local void gf2_matrix_square(unsigned long *square, unsigned long *mat)
360{
361 int n;
362
363 for (n = 0; n < GF2_DIM; n++)
364 square[n] = gf2_matrix_times(mat, mat[n]);
365}
366
367/* ========================================================================= */
369{
370 int n;
371 unsigned long row;
372 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
373 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
374
375 /* degenerate case (also disallow negative lengths) */
376 if (len2 <= 0)
377 return crc1;
378
379 /* put operator for one zero bit in odd */
380 odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
381 row = 1;
382 for (n = 1; n < GF2_DIM; n++) {
383 odd[n] = row;
384 row <<= 1;
385 }
386
387 /* put operator for two zero bits in even */
388 gf2_matrix_square(even, odd);
389
390 /* put operator for four zero bits in odd */
391 gf2_matrix_square(odd, even);
392
393 /* apply len2 zeros to crc1 (first square will put the operator for one
394 zero byte, eight zero bits, in even) */
395 do {
396 /* apply zeros operator for this bit of len2 */
397 gf2_matrix_square(even, odd);
398 if (len2 & 1)
399 crc1 = gf2_matrix_times(even, crc1);
400 len2 >>= 1;
401
402 /* if no more bits set, then done */
403 if (len2 == 0)
404 break;
405
406 /* another iteration of the loop with odd and even swapped */
407 gf2_matrix_square(odd, even);
408 if (len2 & 1)
409 crc1 = gf2_matrix_times(odd, crc1);
410 len2 >>= 1;
411
412 /* if no more bits set, then done */
413 } while (len2 != 0);
414
415 /* return combined crc */
416 crc1 ^= crc2;
417 return crc1;
418}
419
420/* ========================================================================= */
422{
423 return crc32_combine_(crc1, crc2, len2);
424}
425
427{
428 return crc32_combine_(crc1, crc2, len2);
429}
430
431
433
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define local
Definition adler32.c:17
#define DO1(buf, i)
Definition adler32.c:25
#define DO8(buf, i)
Definition adler32.c:28
#define TBLS
Definition crc32.c:73
#define GF2_DIM
Definition crc32.c:341
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2)
Definition crc32.c:368
local unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec)
Definition crc32.c:344
local void gf2_matrix_square(unsigned long *square, unsigned long *mat)
Definition crc32.c:359
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2)
Definition crc32.c:421
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2)
Definition crc32.c:426
ABC_NAMESPACE_IMPL_END ABC_NAMESPACE_IMPL_START const unsigned long FAR *ZEXPORT get_crc_table()
Definition crc32.c:216
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition crc32.c:230
ABC_NAMESPACE_HEADER_START local const unsigned long FAR crc_table[TBLS][256]
Definition crc32.h:7
Cube * p
Definition exorList.c:222
#define ZEXPORT
Definition zconf.h:322
unsigned int uInt
Definition zconf.h:335
#define z_off_t
Definition zconf.h:396
#define OF(args)
Definition zconf.h:242
#define z_off64_t
Definition zconf.h:402
unsigned long uLong
Definition zconf.h:336
#define FAR
Definition zconf.h:329
#define Z_NULL
Definition zlib.h:216