Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
adler32.c
00001 /* adler32.c -- compute the Adler-32 checksum of a data stream 00002 * Copyright (C) 1995-2011 Mark Adler 00003 * For conditions of distribution and use, see copyright notice in zlib.h 00004 */ 00005 00006 /* @(#) $Id$ */ 00007 00008 #include "zutil.h" 00009 00010 #define local static 00011 00012 local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); 00013 00014 #define BASE 65521 /* largest prime smaller than 65536 */ 00015 #define NMAX 5552 00016 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ 00017 00018 #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} 00019 #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); 00020 #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); 00021 #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); 00022 #define DO16(buf) DO8(buf,0); DO8(buf,8); 00023 00024 /* use NO_DIVIDE if your processor does not do division in hardware -- 00025 try it both ways to see which is faster */ 00026 #ifdef NO_DIVIDE 00027 /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 00028 (thank you to John Reiser for pointing this out) */ 00029 # define CHOP(a) \ 00030 do { \ 00031 unsigned long tmp = a >> 16; \ 00032 a &= 0xffffUL; \ 00033 a += (tmp << 4) - tmp; \ 00034 } while (0) 00035 # define MOD28(a) \ 00036 do { \ 00037 CHOP(a); \ 00038 if (a >= BASE) a -= BASE; \ 00039 } while (0) 00040 # define MOD(a) \ 00041 do { \ 00042 CHOP(a); \ 00043 MOD28(a); \ 00044 } while (0) 00045 # define MOD63(a) \ 00046 do { /* this assumes a is not negative */ \ 00047 z_off64_t tmp = a >> 32; \ 00048 a &= 0xffffffffL; \ 00049 a += (tmp << 8) - (tmp << 5) + tmp; \ 00050 tmp = a >> 16; \ 00051 a &= 0xffffL; \ 00052 a += (tmp << 4) - tmp; \ 00053 tmp = a >> 16; \ 00054 a &= 0xffffL; \ 00055 a += (tmp << 4) - tmp; \ 00056 if (a >= BASE) a -= BASE; \ 00057 } while (0) 00058 #else 00059 # define MOD(a) a %= BASE 00060 # define MOD28(a) a %= BASE 00061 # define MOD63(a) a %= BASE 00062 #endif 00063 00064 /* ========================================================================= */ 00065 uLong ZEXPORT adler32(adler, buf, len) 00066 uLong adler; 00067 const Bytef *buf; 00068 uInt len; 00069 { 00070 unsigned long sum2; 00071 unsigned n; 00072 00073 /* split Adler-32 into component sums */ 00074 sum2 = (adler >> 16) & 0xffff; 00075 adler &= 0xffff; 00076 00077 /* in case user likes doing a byte at a time, keep it fast */ 00078 if (len == 1) { 00079 adler += buf[0]; 00080 if (adler >= BASE) 00081 adler -= BASE; 00082 sum2 += adler; 00083 if (sum2 >= BASE) 00084 sum2 -= BASE; 00085 return adler | (sum2 << 16); 00086 } 00087 00088 /* initial Adler-32 value (deferred check for len == 1 speed) */ 00089 if (buf == Z_NULL) 00090 return 1L; 00091 00092 /* in case short lengths are provided, keep it somewhat fast */ 00093 if (len < 16) { 00094 while (len--) { 00095 adler += *buf++; 00096 sum2 += adler; 00097 } 00098 if (adler >= BASE) 00099 adler -= BASE; 00100 MOD28(sum2); /* only added so many BASE's */ 00101 return adler | (sum2 << 16); 00102 } 00103 00104 /* do length NMAX blocks -- requires just one modulo operation */ 00105 while (len >= NMAX) { 00106 len -= NMAX; 00107 n = NMAX / 16; /* NMAX is divisible by 16 */ 00108 do { 00109 DO16(buf); /* 16 sums unrolled */ 00110 buf += 16; 00111 } while (--n); 00112 MOD(adler); 00113 MOD(sum2); 00114 } 00115 00116 /* do remaining bytes (less than NMAX, still just one modulo) */ 00117 if (len) { /* avoid modulos if none remaining */ 00118 while (len >= 16) { 00119 len -= 16; 00120 DO16(buf); 00121 buf += 16; 00122 } 00123 while (len--) { 00124 adler += *buf++; 00125 sum2 += adler; 00126 } 00127 MOD(adler); 00128 MOD(sum2); 00129 } 00130 00131 /* return recombined sums */ 00132 return adler | (sum2 << 16); 00133 } 00134 00135 /* ========================================================================= */ 00136 local uLong adler32_combine_(adler1, adler2, len2) 00137 uLong adler1; 00138 uLong adler2; 00139 z_off64_t len2; 00140 { 00141 unsigned long sum1; 00142 unsigned long sum2; 00143 unsigned rem; 00144 00145 /* for negative len, return invalid adler32 as a clue for debugging */ 00146 if (len2 < 0) 00147 return 0xffffffffUL; 00148 00149 /* the derivation of this formula is left as an exercise for the reader */ 00150 MOD63(len2); /* assumes len2 >= 0 */ 00151 rem = (unsigned)len2; 00152 sum1 = adler1 & 0xffff; 00153 sum2 = rem * sum1; 00154 MOD(sum2); 00155 sum1 += (adler2 & 0xffff) + BASE - 1; 00156 sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 00157 if (sum1 >= BASE) sum1 -= BASE; 00158 if (sum1 >= BASE) sum1 -= BASE; 00159 if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); 00160 if (sum2 >= BASE) sum2 -= BASE; 00161 return sum1 | (sum2 << 16); 00162 } 00163 00164 /* ========================================================================= */ 00165 uLong ZEXPORT adler32_combine(adler1, adler2, len2) 00166 uLong adler1; 00167 uLong adler2; 00168 z_off_t len2; 00169 { 00170 return adler32_combine_(adler1, adler2, len2); 00171 } 00172 00173 uLong ZEXPORT adler32_combine64(adler1, adler2, len2) 00174 uLong adler1; 00175 uLong adler2; 00176 z_off64_t len2; 00177 { 00178 return adler32_combine_(adler1, adler2, len2); 00179 }
Generated on Wed Jul 13 2022 09:05:31 by
1.7.2