19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* crc32.c -- compute the CRC-32 of a data stream 209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler 39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h 49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * tables for updating the shift register in one step with three exclusive-ors 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * instead of four steps with four exclusive-ors. This results in about a 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* @(#) $Id$ */ 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project protection on the static variables used to control the first-use generation 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project first call get_crc_table() to initialize the tables before allowing more than 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project one thread to use crc32(). 20ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 21ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# include <stdio.h> 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# ifndef DYNAMIC_CRC_TABLE 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define DYNAMIC_CRC_TABLE 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# endif /* !DYNAMIC_CRC_TABLE */ 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */ 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zutil.h" /* for STDC and FAR definitions */ 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define local static 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Definitions for doing the crc four data bytes at a time. */ 3609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#if !defined(NOBYFOUR) && defined(Z_U4) 3709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes# define BYFOUR 3809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes#endif 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project local unsigned long crc32_little OF((unsigned long, 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project const unsigned char FAR *, unsigned)); 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project local unsigned long crc32_big OF((unsigned long, 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project const unsigned char FAR *, unsigned)); 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define TBLS 8 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define TBLS 1 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */ 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Local functions for crc concatenation */ 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long gf2_matrix_times OF((unsigned long *mat, 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long vec)); 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); 53ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hugheslocal uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); 54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal volatile int crc_table_empty = 1; 5909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hugheslocal z_crc_t FAR crc_table[TBLS][256]; 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void make_crc_table OF((void)); 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH 6209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes local void write_table OF((FILE *, const z_crc_t FAR *)); 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */ 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 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. 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Polynomials over GF(2) are represented in binary, one bit per coefficient, 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project with the lowest powers in the most significant bit. Then adding polynomials 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is just exclusive-or, and multiplying a polynomial by x is a right shift by 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project one. If we call the above polynomial p, and represent a byte as the 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project polynomial q, also with the lowest power in the most significant bit (so the 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project where a mod b means the remainder after dividing a by b. 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project This calculation is done using the shift-register method of multiplying and 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project taking the remainder. The register is initialized to zero, and for each 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project incoming bit, x^32 is added mod p to the register if the bit is a one (where 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project x (which is shifting right by one and adding x^32 mod p if the bit shifted 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out is a one). We start with the highest power (least significant bit) of 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project q and repeat for all eight bits of q. 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project The first table is simply the CRC of all possible eight bit values. This is 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project all the information needed to generate CRCs on data a byte at a time for all 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project combinations of CRC register values and incoming bytes. The remaining tables 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project allow for word-at-a-time CRC calculation for both big-endian and little- 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project endian machines, where a word is four bytes. 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/ 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void make_crc_table() 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 9209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes z_crc_t c; 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int n, k; 9409eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes z_crc_t poly; /* polynomial exclusive-or pattern */ 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* terms of polynomial defining this crc (except x^32): */ 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static volatile int first = 1; /* flag to limit concurrent making */ 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* See if another task is already doing this (not thread-safe, but better 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project than nothing -- significantly reduces duration of vulnerability in 1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case the advice about DYNAMIC_CRC_TABLE is ignored) */ 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (first) { 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project first = 0; 1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* make exclusive-or pattern from polynomial (0xedb88320UL) */ 106ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes poly = 0; 107ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) 10809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes poly |= (z_crc_t)1 << (31 - p[n]); 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* generate a crc for every 8-bit value */ 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (n = 0; n < 256; n++) { 11209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes c = (z_crc_t)n; 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (k = 0; k < 8; k++) 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = c & 1 ? poly ^ (c >> 1) : c >> 1; 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc_table[0][n] = c; 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* generate crc for each value followed by one, two, and three zeros, 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and then the byte reversal of those as well as the first table */ 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (n = 0; n < 256; n++) { 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[0][n]; 12309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes crc_table[4][n] = ZSWAP32(c); 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (k = 1; k < 4; k++) { 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[0][c & 0xff] ^ (c >> 8); 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc_table[k][n] = c; 12709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes crc_table[k + 4][n] = ZSWAP32(c); 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */ 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc_table_empty = 0; 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { /* not first */ 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* wait for the other guy to finish (not efficient, but rare) */ 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (crc_table_empty) 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ; 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write out CRC tables to crc32.h */ 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project { 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE *out; 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out = fopen("crc32.h", "w"); 1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (out == NULL) return; 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); 14909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes fprintf(out, "local const z_crc_t FAR "); 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project write_table(out, crc_table[0]); 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# ifdef BYFOUR 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, "#ifdef BYFOUR\n"); 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (k = 1; k < 8; k++) { 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, " },\n {\n"); 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project write_table(out, crc_table[k]); 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, "#endif\n"); 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# endif /* BYFOUR */ 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fprintf(out, " }\n};\n"); 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fclose(out); 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */ 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKECRCH 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void write_table(out, table) 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project FILE *out; 16909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes const z_crc_t FAR *table; 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int n; 1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (n = 0; n < 256; n++) 174ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", 175ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (unsigned long)(table[n]), 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKECRCH */ 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else /* !DYNAMIC_CRC_TABLE */ 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ======================================================================== 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Tables of CRC-32s of all single-byte values, made by make_crc_table(). 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "crc32.h" 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */ 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * This function can be used by asm versions of crc32() 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 19009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughesconst z_crc_t FAR * ZEXPORT get_crc_table() 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (crc_table_empty) 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project make_crc_table(); 1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */ 19609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes return (const z_crc_t FAR *)crc_table; 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned long ZEXPORT crc32(crc, buf, len) 2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long crc; 2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project const unsigned char FAR *buf; 207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes uInt len; 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (buf == Z_NULL) return 0UL; 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef DYNAMIC_CRC_TABLE 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (crc_table_empty) 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project make_crc_table(); 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* DYNAMIC_CRC_TABLE */ 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (sizeof(void *) == sizeof(ptrdiff_t)) { 21809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes z_crc_t endian; 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project endian = 1; 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (*((unsigned char *)(&endian))) 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return crc32_little(crc, buf, len); 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return crc32_big(crc, buf, len); 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */ 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc = crc ^ 0xffffffffUL; 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len >= 8) { 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DO8; 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 8; 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len) do { 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DO1; 2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (--len); 2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return crc ^ 0xffffffffUL; 2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BYFOUR 2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOLIT4 c ^= *buf4++; \ 2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ 2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] 2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long crc32_little(crc, buf, len) 2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long crc; 2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project const unsigned char FAR *buf; 2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 25209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes register z_crc_t c; 25309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes register const z_crc_t FAR *buf4; 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 25509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes c = (z_crc_t)crc; 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = ~c; 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len && ((ptrdiff_t)buf & 3)) { 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len--; 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 26209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes buf4 = (const z_crc_t FAR *)(const void FAR *)buf; 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len >= 32) { 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DOLIT32; 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 32; 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len >= 4) { 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DOLIT4; 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 4; 2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf = (const unsigned char FAR *)buf4; 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len) do { 2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (--len); 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = ~c; 2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return (unsigned long)c; 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOBIG4 c ^= *++buf4; \ 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long crc32_big(crc, buf, len) 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long crc; 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project const unsigned char FAR *buf; 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 29209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes register z_crc_t c; 29309eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes register const z_crc_t FAR *buf4; 2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 29509eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes c = ZSWAP32((z_crc_t)crc); 2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = ~c; 2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len && ((ptrdiff_t)buf & 3)) { 2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); 2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len--; 3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 30209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes buf4 = (const z_crc_t FAR *)(const void FAR *)buf; 3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf4--; 3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len >= 32) { 3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DOBIG32; 3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 32; 3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (len >= 4) { 3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DOBIG4; 3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len -= 4; 3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf4++; 3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf = (const unsigned char FAR *)buf4; 3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len) do { 3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); 3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (--len); 3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project c = ~c; 31909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes return (unsigned long)(ZSWAP32(c)); 3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BYFOUR */ 3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ 3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned long gf2_matrix_times(mat, vec) 3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long *mat; 3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long vec; 3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long sum; 3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sum = 0; 3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (vec) { 3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (vec & 1) 3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sum ^= *mat; 3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project vec >>= 1; 3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mat++; 3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return sum; 3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void gf2_matrix_square(square, mat) 3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long *square; 3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long *mat; 3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int n; 3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (n = 0; n < GF2_DIM; n++) 3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project square[n] = gf2_matrix_times(mat, mat[n]); 3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ========================================================================= */ 355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal uLong crc32_combine_(crc1, crc2, len2) 3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project uLong crc1; 3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project uLong crc2; 358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t len2; 3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int n; 3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long row; 3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ 3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ 3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 365381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* degenerate case (also disallow negative lengths) */ 366381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (len2 <= 0) 3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return crc1; 3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* put operator for one zero bit in odd */ 370381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ 3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project row = 1; 3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (n = 1; n < GF2_DIM; n++) { 3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project odd[n] = row; 3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project row <<= 1; 3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* put operator for two zero bits in even */ 3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gf2_matrix_square(even, odd); 3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* put operator for four zero bits in odd */ 3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gf2_matrix_square(odd, even); 3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* apply len2 zeros to crc1 (first square will put the operator for one 3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zero byte, eight zero bits, in even) */ 3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* apply zeros operator for this bit of len2 */ 3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gf2_matrix_square(even, odd); 3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len2 & 1) 3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc1 = gf2_matrix_times(even, crc1); 3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len2 >>= 1; 3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if no more bits set, then done */ 3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len2 == 0) 3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* another iteration of the loop with odd and even swapped */ 3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gf2_matrix_square(odd, even); 3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len2 & 1) 3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc1 = gf2_matrix_times(odd, crc1); 4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len2 >>= 1; 4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if no more bits set, then done */ 4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (len2 != 0); 4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* return combined crc */ 4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project crc1 ^= crc2; 4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return crc1; 4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 410381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* ========================================================================= */ 411381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesuLong ZEXPORT crc32_combine(crc1, crc2, len2) 412381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes uLong crc1; 413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes uLong crc2; 414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off_t len2; 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return crc32_combine_(crc1, crc2, len2); 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 418381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 419381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesuLong ZEXPORT crc32_combine64(crc1, crc2, len2) 420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes uLong crc1; 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes uLong crc2; 422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes z_off64_t len2; 423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return crc32_combine_(crc1, crc2, len2); 425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 426