• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* crc32.c -- output crc32 tables
2  * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016, 2018 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5 
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include "zbuild.h"
9 #include "deflate.h"
10 #include "crc32_p.h"
11 
12 static uint32_t crc_table[8][256];
13 static uint32_t crc_comb[GF2_DIM][GF2_DIM];
14 
15 static void gf2_matrix_square(uint32_t *square, const uint32_t *mat);
16 static void make_crc_table(void);
17 static void make_crc_combine_table(void);
18 static void print_crc_table(void);
19 static void print_crc_combine_table(void);
20 static void write_table(const uint32_t *, int);
21 
22 
23 /* ========================================================================= */
gf2_matrix_square(uint32_t * square,const uint32_t * mat)24 static void gf2_matrix_square(uint32_t *square, const uint32_t *mat) {
25     int n;
26 
27     for (n = 0; n < GF2_DIM; n++)
28         square[n] = gf2_matrix_times(mat, mat[n]);
29 }
30 
31 /* =========================================================================
32   Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
33   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.
34 
35   Polynomials over GF(2) are represented in binary, one bit per coefficient,
36   with the lowest powers in the most significant bit.  Then adding polynomials
37   is just exclusive-or, and multiplying a polynomial by x is a right shift by
38   one.  If we call the above polynomial p, and represent a byte as the
39   polynomial q, also with the lowest power in the most significant bit (so the
40   byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
41   where a mod b means the remainder after dividing a by b.
42 
43   This calculation is done using the shift-register method of multiplying and
44   taking the remainder.  The register is initialized to zero, and for each
45   incoming bit, x^32 is added mod p to the register if the bit is a one (where
46   x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
47   x (which is shifting right by one and adding x^32 mod p if the bit shifted
48   out is a one).  We start with the highest power (least significant bit) of
49   q and repeat for all eight bits of q.
50 
51   The first table is simply the CRC of all possible eight bit values.  This is
52   all the information needed to generate CRCs on data a byte at a time for all
53   combinations of CRC register values and incoming bytes.  The remaining tables
54   allow for word-at-a-time CRC calculation for both big-endian and little-
55   endian machines, where a word is four bytes.
56 */
make_crc_table(void)57 static void make_crc_table(void) {
58     int n, k;
59     uint32_t c;
60     uint32_t poly;                       /* polynomial exclusive-or pattern */
61     /* terms of polynomial defining this crc (except x^32): */
62     static const unsigned char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26};
63 
64     /* make exclusive-or pattern from polynomial (0xedb88320) */
65     poly = 0;
66     for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
67         poly |= (uint32_t)1 << (31 - p[n]);
68 
69     /* generate a crc for every 8-bit value */
70     for (n = 0; n < 256; n++) {
71         c = (uint32_t)n;
72         for (k = 0; k < 8; k++)
73             c = c & 1 ? poly ^ (c >> 1) : c >> 1;
74         crc_table[0][n] = c;
75     }
76 
77     /* generate crc for each value followed by one, two, and three zeros,
78        and then the byte reversal of those as well as the first table */
79     for (n = 0; n < 256; n++) {
80         c = crc_table[0][n];
81         crc_table[4][n] = ZSWAP32(c);
82         for (k = 1; k < 4; k++) {
83             c = crc_table[0][c & 0xff] ^ (c >> 8);
84             crc_table[k][n] = c;
85             crc_table[k + 4][n] = ZSWAP32(c);
86         }
87     }
88 }
89 
make_crc_combine_table(void)90 static void make_crc_combine_table(void) {
91     int n, k;
92     /* generate zero operators table for crc32_combine() */
93 
94     /* generate the operator to apply a single zero bit to a CRC -- the
95        first row adds the polynomial if the low bit is a 1, and the
96        remaining rows shift the CRC right one bit */
97     k = GF2_DIM - 3;
98     crc_comb[k][0] = 0xedb88320UL;      /* CRC-32 polynomial */
99     uint32_t row = 1;
100     for (n = 1; n < GF2_DIM; n++) {
101         crc_comb[k][n] = row;
102         row <<= 1;
103     }
104     /* generate operators that apply 2, 4, and 8 zeros to a CRC, putting
105        the last one, the operator for one zero byte, at the 0 position */
106     gf2_matrix_square(crc_comb[k + 1], crc_comb[k]);
107     gf2_matrix_square(crc_comb[k + 2], crc_comb[k + 1]);
108     gf2_matrix_square(crc_comb[0], crc_comb[k + 2]);
109 
110     /* generate operators for applying 2^n zero bytes to a CRC, filling out
111        the remainder of the table -- the operators repeat after GF2_DIM
112        values of n, so the table only needs GF2_DIM entries, regardless of
113        the size of the length being processed */
114     for (n = 1; n < k; n++)
115         gf2_matrix_square(crc_comb[n], crc_comb[n - 1]);
116 }
117 
write_table(const uint32_t * table,int k)118 static void write_table(const uint32_t *table, int k) {
119     int n;
120 
121     for (n = 0; n < k; n++)
122         printf("%s0x%08" PRIx32 "%s", n % 5 ? "" : "    ",
123                 (uint32_t)(table[n]),
124                 n == k - 1 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
125 }
126 
print_crc_table(void)127 static void print_crc_table(void) {
128     int k;
129     printf("#ifndef CRC32_TBL_H_\n");
130     printf("#define CRC32_TBL_H_\n\n");
131     printf("/* crc32_tbl.h -- tables for rapid CRC calculation\n");
132     printf(" * Generated automatically by makecrct.c\n */\n\n");
133 
134     /* print CRC table */
135     printf("static const uint32_t ");
136     printf("crc_table[8][256] =\n{\n  {\n");
137     write_table(crc_table[0], 256);
138     for (k = 1; k < 8; k++) {
139         printf("  },\n  {\n");
140         write_table(crc_table[k], 256);
141     }
142     printf("  }\n};\n\n");
143 
144     printf("#endif /* CRC32_TBL_H_ */\n");
145 }
146 
print_crc_combine_table(void)147 static void print_crc_combine_table(void) {
148     int k;
149     printf("#ifndef CRC32_COMB_TBL_H_\n");
150     printf("#define CRC32_COMB_TBL_H_\n\n");
151     printf("/* crc32_comb_tbl.h -- zero operators table for CRC combine\n");
152     printf(" * Generated automatically by makecrct.c\n */\n\n");
153 
154     /* print zero operator table */
155     printf("static const uint32_t ");
156     printf("crc_comb[%d][%d] =\n{\n  {\n", GF2_DIM, GF2_DIM);
157     write_table(crc_comb[0], GF2_DIM);
158     for (k = 1; k < GF2_DIM; k++) {
159         printf("  },\n  {\n");
160         write_table(crc_comb[k], GF2_DIM);
161     }
162     printf("  }\n};\n\n");
163 
164     printf("#endif /* CRC32_COMB_TBL_H_ */\n");
165 }
166 
167 // The output of this application can be piped out to recreate crc32.h
main(int argc,char * argv[])168 int main(int argc, char *argv[]) {
169     if (argc > 1 && strcmp(argv[1], "-c") == 0) {
170         make_crc_combine_table();
171         print_crc_combine_table();
172     } else {
173         make_crc_table();
174         print_crc_table();
175     }
176     return 0;
177 }
178