Annotation of embedaddon/rsync/zlib/crc32.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>