ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
adler32.c
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file adler32.c
1 /* adler32.c -- compute the Adler-32 checksum of a data stream
2  * Copyright (C) 1995-2011, 2016 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 
7 #include "zutil.h"
8 
9 local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
10 
11 #define BASE 65521U /* largest prime smaller than 65536 */
12 #define NMAX 5552
13 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
14 
15 #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
16 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
17 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
18 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
19 #define DO16(buf) DO8(buf,0); DO8(buf,8);
20 
21 /* use NO_DIVIDE if your processor does not do division in hardware --
22  try it both ways to see which is faster */
23 #ifdef NO_DIVIDE
24 /* note that this assumes BASE is 65521, where 65536 % 65521 == 15
25  (thank you to John Reiser for pointing this out) */
26 # define CHOP(a) \
27  do { \
28  unsigned long tmp = a >> 16; \
29  a &= 0xffffUL; \
30  a += (tmp << 4) - tmp; \
31  } while (0)
32 # define MOD28(a) \
33  do { \
34  CHOP(a); \
35  if (a >= BASE) a -= BASE; \
36  } while (0)
37 # define MOD(a) \
38  do { \
39  CHOP(a); \
40  MOD28(a); \
41  } while (0)
42 # define MOD63(a) \
43  do { /* this assumes a is not negative */ \
44  z_off64_t tmp = a >> 32; \
45  a &= 0xffffffffL; \
46  a += (tmp << 8) - (tmp << 5) + tmp; \
47  tmp = a >> 16; \
48  a &= 0xffffL; \
49  a += (tmp << 4) - tmp; \
50  tmp = a >> 16; \
51  a &= 0xffffL; \
52  a += (tmp << 4) - tmp; \
53  if (a >= BASE) a -= BASE; \
54  } while (0)
55 #else
56 # define MOD(a) a %= BASE
57 # define MOD28(a) a %= BASE
58 # define MOD63(a) a %= BASE
59 #endif
60 
61 /* ========================================================================= */
62 uLong ZEXPORT adler32_z(adler, buf, len)
63  uLong adler;
64  const Bytef *buf;
65  z_size_t len;
66 {
67  unsigned long sum2;
68  unsigned n;
69 
70  /* split Adler-32 into component sums */
71  sum2 = (adler >> 16) & 0xffff;
72  adler &= 0xffff;
73 
74  /* in case user likes doing a byte at a time, keep it fast */
75  if (len == 1) {
76  adler += buf[0];
77  if (adler >= BASE)
78  adler -= BASE;
79  sum2 += adler;
80  if (sum2 >= BASE)
81  sum2 -= BASE;
82  return adler | (sum2 << 16);
83  }
84 
85  /* initial Adler-32 value (deferred check for len == 1 speed) */
86  if (buf == Z_NULL)
87  return 1L;
88 
89  /* in case short lengths are provided, keep it somewhat fast */
90  if (len < 16) {
91  while (len--) {
92  adler += *buf++;
93  sum2 += adler;
94  }
95  if (adler >= BASE)
96  adler -= BASE;
97  MOD28(sum2); /* only added so many BASE's */
98  return adler | (sum2 << 16);
99  }
100 
101  /* do length NMAX blocks -- requires just one modulo operation */
102  while (len >= NMAX) {
103  len -= NMAX;
104  n = NMAX / 16; /* NMAX is divisible by 16 */
105  do {
106  DO16(buf); /* 16 sums unrolled */
107  buf += 16;
108  } while (--n);
109  MOD(adler);
110  MOD(sum2);
111  }
112 
113  /* do remaining bytes (less than NMAX, still just one modulo) */
114  if (len) { /* avoid modulos if none remaining */
115  while (len >= 16) {
116  len -= 16;
117  DO16(buf);
118  buf += 16;
119  }
120  while (len--) {
121  adler += *buf++;
122  sum2 += adler;
123  }
124  MOD(adler);
125  MOD(sum2);
126  }
127 
128  /* return recombined sums */
129  return adler | (sum2 << 16);
130 }
131 
132 /* ========================================================================= */
133 uLong ZEXPORT adler32(adler, buf, len)
134  uLong adler;
135  const Bytef *buf;
136  uInt len;
137 {
138  return adler32_z(adler, buf, len);
139 }
140 
141 /* ========================================================================= */
142 local uLong adler32_combine_(adler1, adler2, len2)
143  uLong adler1;
144  uLong adler2;
145  z_off64_t len2;
146 {
147  unsigned long sum1;
148  unsigned long sum2;
149  unsigned rem;
150 
151  /* for negative len, return invalid adler32 as a clue for debugging */
152  if (len2 < 0)
153  return 0xffffffffUL;
154 
155  /* the derivation of this formula is left as an exercise for the reader */
156  MOD63(len2); /* assumes len2 >= 0 */
157  rem = (unsigned)len2;
158  sum1 = adler1 & 0xffff;
159  sum2 = rem * sum1;
160  MOD(sum2);
161  sum1 += (adler2 & 0xffff) + BASE - 1;
162  sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
163  if (sum1 >= BASE) sum1 -= BASE;
164  if (sum1 >= BASE) sum1 -= BASE;
165  if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
166  if (sum2 >= BASE) sum2 -= BASE;
167  return sum1 | (sum2 << 16);
168 }
169 
170 /* ========================================================================= */
171 uLong ZEXPORT adler32_combine(adler1, adler2, len2)
172  uLong adler1;
173  uLong adler2;
174  z_off_t len2;
175 {
176  return adler32_combine_(adler1, adler2, len2);
177 }
178 
179 uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
180  uLong adler1;
181  uLong adler2;
182  z_off64_t len2;
183 {
184  return adler32_combine_(adler1, adler2, len2);
185 }