cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
adler32.c
Go to the documentation of this file.
1 /* adler32.c -- compute the Adler-32 checksum of a data stream
2  * Copyright (C) 1995-2007 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 /* @(#) $Id$ */
7 
8 #if defined( __MVS__ ) /* pcg */
9  /* MVS control section (CSECT) names default to the file name and cannot
10  match any extern function name in the file. This only applies to the
11  CSECT compiler option. Without a csect name, when maintenance is
12  applied to an MVS program the newly introduced csect is ordered ahead
13  of the previos csects. With csect names, the new csect replaces the
14  old csect. So without csect names, as maintenance is applied
15  throughout the life of the executable, the executable size
16  continually increases--not a good thing.
17 
18  These files required the pragma since they contained external function
19  names that matched the file names, which is the default csect name
20  generated by the compiler with the csect option. You cannot have the
21  same externally visible name defined for two different entities */
22  #pragma csect( CODE, "adler32C" )
23  #pragma csect( STATIC, "adler32S" )
24  #pragma csect( TEST, "adler32T" )
25 #endif /* __MVS__ */
26 
27 #define ZLIB_INTERNAL /* pcg */
28 #if defined( INC_ALL )
29  #include "zutil.h"
30 #else
31  #include "zlib/zutil.h"
32 #endif /* Compiler-specific includes */
33 
34 #define local static
35 
36 local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
37 
38 #define BASE 65521UL /* largest prime smaller than 65536 */
39 #define NMAX 5552
40 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
41 
42 #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
43 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
44 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
45 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
46 #define DO16(buf) DO8(buf,0); DO8(buf,8);
47 
48 /* use NO_DIVIDE if your processor does not do division in hardware */
49 #ifdef NO_DIVIDE
50 # define MOD(a) \
51  do { \
52  if (a >= (BASE << 16)) a -= (BASE << 16); \
53  if (a >= (BASE << 15)) a -= (BASE << 15); \
54  if (a >= (BASE << 14)) a -= (BASE << 14); \
55  if (a >= (BASE << 13)) a -= (BASE << 13); \
56  if (a >= (BASE << 12)) a -= (BASE << 12); \
57  if (a >= (BASE << 11)) a -= (BASE << 11); \
58  if (a >= (BASE << 10)) a -= (BASE << 10); \
59  if (a >= (BASE << 9)) a -= (BASE << 9); \
60  if (a >= (BASE << 8)) a -= (BASE << 8); \
61  if (a >= (BASE << 7)) a -= (BASE << 7); \
62  if (a >= (BASE << 6)) a -= (BASE << 6); \
63  if (a >= (BASE << 5)) a -= (BASE << 5); \
64  if (a >= (BASE << 4)) a -= (BASE << 4); \
65  if (a >= (BASE << 3)) a -= (BASE << 3); \
66  if (a >= (BASE << 2)) a -= (BASE << 2); \
67  if (a >= (BASE << 1)) a -= (BASE << 1); \
68  if (a >= BASE) a -= BASE; \
69  } while (0)
70 # define MOD4(a) \
71  do { \
72  if (a >= (BASE << 4)) a -= (BASE << 4); \
73  if (a >= (BASE << 3)) a -= (BASE << 3); \
74  if (a >= (BASE << 2)) a -= (BASE << 2); \
75  if (a >= (BASE << 1)) a -= (BASE << 1); \
76  if (a >= BASE) a -= BASE; \
77  } while (0)
78 #else
79 # define MOD(a) a %= BASE
80 # define MOD4(a) a %= BASE
81 #endif
82 
83 /* ========================================================================= */
84 uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) /* pcg */
85 {
86  unsigned long sum2;
87  unsigned n;
88 
89  /* split Adler-32 into component sums */
90  sum2 = (adler >> 16) & 0xffff;
91  adler &= 0xffff;
92 
93  /* in case user likes doing a byte at a time, keep it fast */
94  if (len == 1) {
95  adler += buf[0];
96  if (adler >= BASE)
97  adler -= BASE;
98  sum2 += adler;
99  if (sum2 >= BASE)
100  sum2 -= BASE;
101  return adler | (sum2 << 16);
102  }
103 
104  /* initial Adler-32 value (deferred check for len == 1 speed) */
105  if (buf == Z_NULL)
106  return 1L;
107 
108  /* in case short lengths are provided, keep it somewhat fast */
109  if (len < 16) {
110  while (len--) {
111  adler += *buf++;
112  sum2 += adler;
113  }
114  if (adler >= BASE)
115  adler -= BASE;
116  MOD4(sum2); /* only added so many BASE's */
117  return adler | (sum2 << 16);
118  }
119 
120  /* do length NMAX blocks -- requires just one modulo operation */
121  while (len >= NMAX) {
122  len -= NMAX;
123  n = NMAX / 16; /* NMAX is divisible by 16 */
124  do {
125  DO16(buf); /* 16 sums unrolled */
126  buf += 16;
127  } while (--n);
128  MOD(adler);
129  MOD(sum2);
130  }
131 
132  /* do remaining bytes (less than NMAX, still just one modulo) */
133  if (len) { /* avoid modulos if none remaining */
134  while (len >= 16) {
135  len -= 16;
136  DO16(buf);
137  buf += 16;
138  }
139  while (len--) {
140  adler += *buf++;
141  sum2 += adler;
142  }
143  MOD(adler);
144  MOD(sum2);
145  }
146 
147  /* return recombined sums */
148  return adler | (sum2 << 16);
149 }
150 
151 /* ========================================================================= */
152 local uLong adler32_combine_(uLong adler1, uLong adler2, z_off_t len2) /* pcg */
153 {
154  unsigned long sum1;
155  unsigned long sum2;
156  unsigned rem;
157 
158  /* the derivation of this formula is left as an exercise for the reader */
159  rem = (unsigned)(len2 % BASE);
160  sum1 = adler1 & 0xffff;
161  sum2 = rem * sum1;
162  MOD(sum2);
163  sum1 += (adler2 & 0xffff) + BASE - 1;
164  sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
165  if (sum1 >= BASE) sum1 -= BASE;
166  if (sum1 >= BASE) sum1 -= BASE;
167  if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
168  if (sum2 >= BASE) sum2 -= BASE;
169  return sum1 | (sum2 << 16);
170 }
171 
172 /* ========================================================================= */
173 uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) /* pcg */
174 {
175  return adler32_combine_(adler1, adler2, len2);
176 }
177 
178 uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) /* pcg */
179 {
180  return adler32_combine_(adler1, adler2, len2);
181 }