crc32.c 9.4 KB
Newer Older
M
Mark Adler 已提交
1
/* crc32.c -- compute the CRC-32 of a data stream
M
Mark Adler 已提交
2 3 4 5 6 7 8 9
 * Copyright (C) 1995-2003 Mark Adler
 * For conditions of distribution and use, see copyright notice in zlib.h
 *
 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
 * tables for updating the shift register in one step with three exclusive-ors
 * instead of four steps with four exclusive-ors.  This results about a 50%
 * increase in speed on a Power PC using gcc -O3.
M
Mark Adler 已提交
10 11
 */

M
Mark Adler 已提交
12
/* @(#) $Id$ */
M
Mark Adler 已提交
13

M
Mark Adler 已提交
14 15 16 17 18 19 20
#ifdef MAKECRCH
#  include <stdio.h>
#  ifndef DYNAMIC_CRC_TABLE
#    define DYNAMIC_CRC_TABLE
#  endif /* !DYNAMIC_CRC_TABLE */
#endif /* MAKECRCH */

M
Mark Adler 已提交
21
#include "zutil.h"
M
Mark Adler 已提交
22

M
Mark Adler 已提交
23
#define local static
M
Mark Adler 已提交
24

M
Mark Adler 已提交
25 26
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR
M
Mark Adler 已提交
27
#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
M
Mark Adler 已提交
28 29
#    include <limits.h>
#    define BYFOUR
M
Mark Adler 已提交
30
#    if (UINT_MAX == 0xffffffffUL)
M
Mark Adler 已提交
31 32
       typedef unsigned int u4;
#    else
M
Mark Adler 已提交
33 34 35 36 37 38 39 40 41
#      if (ULONG_MAX == 0xffffffffUL)
         typedef unsigned long u4;
#      else
#        if (USHRT_MAX == 0xffffffffUL)
           typedef unsigned short u4;
#        else
#          undef BYFOUR     /* can't find a four-byte integer type! */
#        endif
#      endif
M
Mark Adler 已提交
42
#    endif
M
Mark Adler 已提交
43
#  endif /* STDC */
M
Mark Adler 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#endif /* !NOBYFOUR */

/* Definitions for doing the crc four data bytes at a time. */
#ifdef BYFOUR
#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
   local unsigned long crc32_little OF((unsigned long,
                        const unsigned char FAR *, unsigned));
   local unsigned long crc32_big OF((unsigned long,
                        const unsigned char FAR *, unsigned));
#  define TBLS 8
#else
#  define TBLS 1
#endif /* BYFOUR */

M
Mark Adler 已提交
59
#ifdef DYNAMIC_CRC_TABLE
M
Mark Adler 已提交
60

M
Mark Adler 已提交
61
local int crc_table_empty = 1;
M
Mark Adler 已提交
62
local unsigned long FAR crc_table[TBLS][256];
M
Mark Adler 已提交
63
local void make_crc_table OF((void));
M
Mark Adler 已提交
64 65 66
#ifdef MAKECRCH
   local void write_table OF((FILE *, const unsigned long FAR *));
#endif /* MAKECRCH */
M
Mark Adler 已提交
67 68

/*
M
Mark Adler 已提交
69
  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
M
Mark Adler 已提交
70
  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.
M
Mark Adler 已提交
71

M
Mark Adler 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
  Polynomials over GF(2) are represented in binary, one bit per coefficient,
  with the lowest powers in the most significant bit.  Then adding polynomials
  is just exclusive-or, and multiplying a polynomial by x is a right shift by
  one.  If we call the above polynomial p, and represent a byte as the
  polynomial q, also 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).  We start with the highest power (least significant bit) of
  q and repeat for all eight bits of q.

M
Mark Adler 已提交
88 89 90 91 92
  The first table is simply the CRC of all possible eight bit values.  This is
  all the information needed to generate CRCs on data a byte at a time for all
  combinations of CRC register values and incoming bytes.  The remaining tables
  allow for word-at-a-time CRC calculation for both big-endian and little-
  endian machines, where a word is four bytes.
M
Mark Adler 已提交
93
*/
M
Mark Adler 已提交
94
local void make_crc_table()
M
Mark Adler 已提交
95
{
M
Mark Adler 已提交
96 97 98 99 100 101
    unsigned long c;
    int n, k;
    unsigned long poly;            /* polynomial exclusive-or pattern */
    /* terms of polynomial defining this crc (except x^32): */
    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};

M
Mark Adler 已提交
102
    /* make exclusive-or pattern from polynomial (0xedb88320UL) */
M
Mark Adler 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
    poly = 0UL;
    for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
        poly |= 1UL << (31 - p[n]);

    /* generate a crc for every 8-bit value */
    for (n = 0; n < 256; n++) {
        c = (unsigned long)n;
        for (k = 0; k < 8; k++)
            c = c & 1 ? poly ^ (c >> 1) : c >> 1;
        crc_table[0][n] = c;
    }

#ifdef BYFOUR
    /* generate crc for each value followed by one, two, and three zeros, and
       then the byte reversal of those as well as the first table */
    for (n = 0; n < 256; n++) {
        c = crc_table[0][n];
        crc_table[4][n] = REV(c);
        for (k = 1; k < 4; k++) {
            c = crc_table[0][c & 0xff] ^ (c >> 8);
            crc_table[k][n] = c;
            crc_table[k + 4][n] = REV(c);
        }
    }
#endif /* BYFOUR */

M
Mark Adler 已提交
129
  crc_table_empty = 0;
M
Mark Adler 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

#ifdef MAKECRCH
    /* write out CRC tables to crc32.h */
    {
        FILE *out;

        out = fopen("crc32.h", "w");
        if (out == NULL) return;
        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
        fprintf(out, "local const unsigned long FAR ");
        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
        write_table(out, crc_table[0]);
#  ifdef BYFOUR
        fprintf(out, "#ifdef BYFOUR\n");
        for (k = 1; k < 8; k++) {
            fprintf(out, "  },\n  {\n");
            write_table(out, crc_table[k]);
        }
        fprintf(out, "#endif\n");
#  endif /* BYFOUR */
        fprintf(out, "  }\n};\n");
        fclose(out);
    }
#endif /* MAKECRCH */
M
Mark Adler 已提交
155
}
M
Mark Adler 已提交
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

#ifdef MAKECRCH
local void write_table(out, table)
    FILE *out;
    const unsigned long FAR *table;
{
    int n;

    for (n = 0; n < 256; n++)
        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
}
#endif /* MAKECRCH */

#else /* !DYNAMIC_CRC_TABLE */
M
Mark Adler 已提交
171
/* ========================================================================
M
Mark Adler 已提交
172
 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
M
Mark Adler 已提交
173
 */
M
Mark Adler 已提交
174 175
#include "crc32.h"
#endif /* DYNAMIC_CRC_TABLE */
M
Mark Adler 已提交
176

M
Mark Adler 已提交
177 178 179
/* =========================================================================
 * This function can be used by asm versions of crc32()
 */
M
Mark Adler 已提交
180
const unsigned long FAR * ZEXPORT get_crc_table()
M
Mark Adler 已提交
181 182 183
{
#ifdef DYNAMIC_CRC_TABLE
  if (crc_table_empty) make_crc_table();
M
Mark Adler 已提交
184 185
#endif /* DYNAMIC_CRC_TABLE */
  return (const unsigned long FAR *)crc_table;
M
Mark Adler 已提交
186 187 188
}

/* ========================================================================= */
M
Mark Adler 已提交
189 190
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
M
Mark Adler 已提交
191 192

/* ========================================================================= */
M
Mark Adler 已提交
193 194 195 196
unsigned long ZEXPORT crc32(crc, buf, len)
    unsigned long crc;
    const unsigned char FAR *buf;
    unsigned len;
M
Mark Adler 已提交
197
{
M
Mark Adler 已提交
198 199
    if (buf == Z_NULL) return 0UL;

M
Mark Adler 已提交
200 201
#ifdef DYNAMIC_CRC_TABLE
    if (crc_table_empty)
M
Mark Adler 已提交
202 203 204 205
        make_crc_table();
#endif /* DYNAMIC_CRC_TABLE */

#ifdef BYFOUR
M
Mark Adler 已提交
206
    {
M
Mark Adler 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
        u4 endian;

        endian = 1;
        if (*((unsigned char *)(&endian)))
            return crc32_little(crc, buf, len);
        else
            return crc32_big(crc, buf, len);
    }
#else /* !BYFOUR */
    crc = crc ^ 0xffffffffUL;
    while (len >= 8) {
        DO8;
        len -= 8;
    }
    if (len) do {
        DO1;
    } while (--len);
    return crc ^ 0xffffffffUL;
#endif /* BYFOUR */
}

#ifdef BYFOUR

/* ========================================================================= */
#define DOLIT4 c ^= *buf4++; \
        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4

/* ========================================================================= */
local unsigned long crc32_little(crc, buf, len)
    unsigned long crc;
    const unsigned char FAR *buf;
    unsigned len;
{
    register u4 c;
    register const u4 FAR *buf4;

    c = (u4)crc;
    c = ~c;
M
Mark Adler 已提交
247
    while (len && ((size_t)buf & 3)) {
M
Mark Adler 已提交
248 249 250 251 252 253 254 255 256 257 258 259
        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
        len--;
    }

    buf4 = (const u4 FAR *)buf;
    while (len >= 32) {
        DOLIT32;
        len -= 32;
    }
    while (len >= 4) {
        DOLIT4;
        len -= 4;
M
Mark Adler 已提交
260
    }
M
Mark Adler 已提交
261 262
    buf = (const unsigned char FAR *)buf4;

M
Mark Adler 已提交
263
    if (len) do {
M
Mark Adler 已提交
264
        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
M
Mark Adler 已提交
265
    } while (--len);
M
Mark Adler 已提交
266 267
    c = ~c;
    return (unsigned long)c;
M
Mark Adler 已提交
268
}
M
Mark Adler 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

/* ========================================================================= */
#define DOBIG4 c ^= *++buf4; \
        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4

/* ========================================================================= */
local unsigned long crc32_big(crc, buf, len)
    unsigned long crc;
    const unsigned char FAR *buf;
    unsigned len;
{
    register u4 c;
    register const u4 FAR *buf4;

    c = REV((u4)crc);
    c = ~c;
M
Mark Adler 已提交
287
    while (len && ((size_t)buf & 3)) {
M
Mark Adler 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
        len--;
    }

    buf4 = (const u4 FAR *)buf;
    buf4--;
    while (len >= 32) {
        DOBIG32;
        len -= 32;
    }
    while (len >= 4) {
        DOBIG4;
        len -= 4;
    }
    buf4++;
    buf = (const unsigned char FAR *)buf4;

    if (len) do {
        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
    } while (--len);
    c = ~c;
    return (unsigned long)(REV(c));
}

#endif /* BYFOUR */