10a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* adler32.c -- compute the Adler-32 checksum of a data stream 20a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath * Copyright (C) 1995-2004 Mark Adler 30a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath * For conditions of distribution and use, see copyright notice in zlib.h 40a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath */ 50a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 60a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* @(#) $Id$ */ 70a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 80a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define ZLIB_INTERNAL 90a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#include "zlib.h" 100a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 110a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define BASE 65521UL /* largest prime smaller than 65536 */ 120a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define NMAX 5552 130a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 140a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 150a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 160a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 170a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 180a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 190a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#define DO16(buf) DO8(buf,0); DO8(buf,8); 200a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 210a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* use NO_DIVIDE if your processor does not do division in hardware */ 220a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#ifdef NO_DIVIDE 230a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath# define MOD(a) \ 240a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath do { \ 250a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 16)) a -= (BASE << 16); \ 260a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 15)) a -= (BASE << 15); \ 270a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 14)) a -= (BASE << 14); \ 280a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 13)) a -= (BASE << 13); \ 290a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 12)) a -= (BASE << 12); \ 300a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 11)) a -= (BASE << 11); \ 310a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 10)) a -= (BASE << 10); \ 320a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 9)) a -= (BASE << 9); \ 330a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 8)) a -= (BASE << 8); \ 340a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 7)) a -= (BASE << 7); \ 350a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 6)) a -= (BASE << 6); \ 360a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 5)) a -= (BASE << 5); \ 370a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 4)) a -= (BASE << 4); \ 380a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 3)) a -= (BASE << 3); \ 390a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 2)) a -= (BASE << 2); \ 400a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 1)) a -= (BASE << 1); \ 410a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= BASE) a -= BASE; \ 420a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } while (0) 430a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath# define MOD4(a) \ 440a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath do { \ 450a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 4)) a -= (BASE << 4); \ 460a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 3)) a -= (BASE << 3); \ 470a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 2)) a -= (BASE << 2); \ 480a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= (BASE << 1)) a -= (BASE << 1); \ 490a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (a >= BASE) a -= BASE; \ 500a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } while (0) 510a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#else 520a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath# define MOD(a) a %= BASE 530a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath# define MOD4(a) a %= BASE 540a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath#endif 550a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 560a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* ========================================================================= */ 570a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 580a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* 590a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath The adler32 code below computes, in effect, 600a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 610a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong high = 0; 620a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong low = 1; 630a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath for (j = 0; j < len; j++) { 640a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath low = (low + buf[j]) % BASE; 650a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath high = (high + low) % BASE; 660a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 670a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath checksum = (high << 16) | low; 680a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 690a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath Both 16-bit halves of the checksum are between 0 and BASE-1 (inclusive). 700a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath Hence, the minimum possible checksum value is 0, and the maximum is 710a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath ((BASE-1) << 16) | (BASE-1). Applications may have reserved values 720a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath outside this range to carry special meanings. 730a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 740a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath NOTE: If adler32() is changed in ANY way, be absolutely sure that the 750a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath change will NOT cause checksums previously stored to not match the data 760a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath they were originally intended to match, or expand the range in such a 770a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath way that values reserved by applications to carry special meanings now 780a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath become checksums of valid data. Also, be sure to change adler32_range() 790a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath accordingly. 800a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 810a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath This explanation and adler32_range() are not part of original software 820a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath distribution. They are added at Google (2006) in accordance with the 830a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath copyright notice in zlib.h, which permits alteration and redistribution 840a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath of the original software provided, among other things, that altered 850a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath source versions must be plainly marked as such and not misrepresented as 860a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath being the original software. 870a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath*/ 880a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 890a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamathvoid ZEXPORT adler32_range(min, max) 900a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong *min; 910a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong *max; 920a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath{ 930a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath *min = 0L; 940a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath *max = ((BASE-1) << 16) | (BASE-1); 950a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath} 960a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 970a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathuLong ZEXPORT adler32(adler, buf, len) 980a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong adler; 990a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath const Bytef *buf; 1000a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uInt len; 1010a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath{ 1020a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath unsigned long sum2; 1030a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath unsigned n; 1040a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1050a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* split Adler-32 into component sums */ 1060a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 = (adler >> 16) & 0xffff; 1070a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler &= 0xffff; 1080a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1090a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* in case user likes doing a byte at a time, keep it fast */ 1100a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (len == 1) { 1110a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler += buf[0]; 1120a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (adler >= BASE) 1130a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler -= BASE; 1140a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 += adler; 1150a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (sum2 >= BASE) 1160a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 -= BASE; 1170a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath return adler | (sum2 << 16); 1180a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1190a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1200a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* initial Adler-32 value (deferred check for len == 1 speed) */ 1210a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (buf == Z_NULL) 1220a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath return 1L; 1230a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1240a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* in case short lengths are provided, keep it somewhat fast */ 1250a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (len < 16) { 1260a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath while (len--) { 1270a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler += *buf++; 1280a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 += adler; 1290a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1300a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (adler >= BASE) 1310a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler -= BASE; 1320a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD4(sum2); /* only added so many BASE's */ 1330a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath return adler | (sum2 << 16); 1340a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1350a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1360a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* do length NMAX blocks -- requires just one modulo operation */ 1370a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath while (len >= NMAX) { 1380a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath len -= NMAX; 1390a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath n = NMAX / 16; /* NMAX is divisible by 16 */ 1400a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath do { 1410a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath DO16(buf); /* 16 sums unrolled */ 1420a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath buf += 16; 1430a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } while (--n); 1440a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD(adler); 1450a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD(sum2); 1460a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1470a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1480a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* do remaining bytes (less than NMAX, still just one modulo) */ 1490a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (len) { /* avoid modulos if none remaining */ 1500a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath while (len >= 16) { 1510a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath len -= 16; 1520a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath DO16(buf); 1530a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath buf += 16; 1540a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1550a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath while (len--) { 1560a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath adler += *buf++; 1570a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 += adler; 1580a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1590a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD(adler); 1600a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD(sum2); 1610a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath } 1620a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1630a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* return recombined sums */ 1640a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath return adler | (sum2 << 16); 1650a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath} 1660a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1670a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath/* ========================================================================= */ 1680a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan KamathuLong ZEXPORT adler32_combine(adler1, adler2, len2) 1690a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong adler1; 1700a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath uLong adler2; 1710a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath z_off_t len2; 1720a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath{ 1730a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath unsigned long sum1; 1740a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath unsigned long sum2; 1750a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath unsigned rem; 1760a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath 1770a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath /* the derivation of this formula is left as an exercise for the reader */ 1780a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath rem = (unsigned)(len2 % BASE); 1790a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum1 = adler1 & 0xffff; 1800a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 = rem * sum1; 1810a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath MOD(sum2); 1820a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum1 += (adler2 & 0xffff) + BASE - 1; 1830a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 1840a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (sum1 >= BASE) sum1 -= BASE; 1850a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (sum1 >= BASE) sum1 -= BASE; 1860a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); 1870a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath if (sum2 >= BASE) sum2 -= BASE; 1880a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath return sum1 | (sum2 << 16); 1890a58c5c2f73e5047b36f12b5f12b12d6f2a9f69dNarayan Kamath} 190