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