Branch data Line data Source code
1 : : /* adler32.c -- compute the Adler-32 checksum of a data stream
2 : : * Copyright (C) 1995-2003 Mark Adler
3 : : * For conditions of distribution and use, see copyright notice in zlib.h
4 : : */
5 : :
6 : : /* @(#) $Id: adler32.c,v 1.1.1.2 2002/03/11 21:53:23 tromey Exp $ */
7 : :
8 : : /* Modified by Jung-Sang Ahn in 2014 */
9 : :
10 : : #include "adler32.h"
11 : :
12 : : #define BASE 65521 /* largest prime smaller than 65536 */
13 : : #define NMAX 5552
14 : : /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
15 : :
16 : : #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
17 : : #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
18 : : #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
19 : : #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
20 : : #define DO16(buf) DO8(buf,0); DO8(buf,8);
21 : :
22 : : /* use NO_DIVIDE if your processor does not do division in hardware --
23 : : try it both ways to see which is faster */
24 : : #ifdef NO_DIVIDE
25 : : /* note that this assumes BASE is 65521, where 65536 % 65521 == 15
26 : : (thank you to John Reiser for pointing this out) */
27 : : # define CHOP(a) \
28 : : do { \
29 : : unsigned long tmp = a >> 16; \
30 : : a &= 0xffffUL; \
31 : : a += (tmp << 4) - tmp; \
32 : : } while (0)
33 : : # define MOD28(a) \
34 : : do { \
35 : : CHOP(a); \
36 : : if (a >= BASE) a -= BASE; \
37 : : } while (0)
38 : : # define MOD(a) \
39 : : do { \
40 : : CHOP(a); \
41 : : MOD28(a); \
42 : : } while (0)
43 : : # define MOD63(a) \
44 : : do { /* this assumes a is not negative */ \
45 : : z_off64_t tmp = a >> 32; \
46 : : a &= 0xffffffffL; \
47 : : a += (tmp << 8) - (tmp << 5) + tmp; \
48 : : tmp = a >> 16; \
49 : : a &= 0xffffL; \
50 : : a += (tmp << 4) - tmp; \
51 : : tmp = a >> 16; \
52 : : a &= 0xffffL; \
53 : : a += (tmp << 4) - tmp; \
54 : : if (a >= BASE) a -= BASE; \
55 : : } while (0)
56 : : #else
57 : : # define MOD(a) a %= BASE
58 : : # define MOD28(a) a %= BASE
59 : : # define MOD63(a) a %= BASE
60 : : #endif
61 : :
62 : : /* ========================================================================= */
63 : 4 : uint32_t adler32(uint32_t adler, uint8_t *buf, size_t len)
64 : : {
65 : : unsigned long sum2;
66 : : unsigned n;
67 : :
68 : : /* split Adler-32 into component sums */
69 : 4 : sum2 = (adler >> 16) & 0xffff;
70 : 4 : adler &= 0xffff;
71 : :
72 : : /* in case user likes doing a byte at a time, keep it fast */
73 [ - + ]: 4 : if (len == 1) {
74 : 0 : adler += buf[0];
75 [ # # ]: 0 : if (adler >= BASE)
76 : 0 : adler -= BASE;
77 : 0 : sum2 += adler;
78 [ # # ]: 0 : if (sum2 >= BASE)
79 : 0 : sum2 -= BASE;
80 : 0 : return adler | (sum2 << 16);
81 : : }
82 : :
83 : : /* initial Adler-32 value (deferred check for len == 1 speed) */
84 [ - + ]: 4 : if (buf == NULL)
85 : 0 : return 1L;
86 : :
87 : : /* in case short lengths are provided, keep it somewhat fast */
88 [ + + ]: 4 : if (len < 16) {
89 [ + + ]: 19 : while (len--) {
90 : 16 : adler += *buf++;
91 : 16 : sum2 += adler;
92 : : }
93 [ - + ]: 3 : if (adler >= BASE)
94 : 0 : adler -= BASE;
95 : 3 : MOD28(sum2); /* only added so many BASE's */
96 : 3 : return adler | (sum2 << 16);
97 : : }
98 : :
99 : : /* do length NMAX blocks -- requires just one modulo operation */
100 [ + + ]: 193398 : while (len >= NMAX) {
101 : 193397 : len -= NMAX;
102 : 193397 : n = NMAX / 16; /* NMAX is divisible by 16 */
103 [ + + ]: 67108759 : do {
104 : 67108759 : DO16(buf); /* 16 sums unrolled */
105 : 67108759 : buf += 16;
106 : : } while (--n);
107 : 193397 : MOD(adler);
108 : 193397 : MOD(sum2);
109 : : }
110 : :
111 : : /* do remaining bytes (less than NMAX, still just one modulo) */
112 [ + - ]: 1 : if (len) { /* avoid modulos if none remaining */
113 [ + + ]: 106 : while (len >= 16) {
114 : 105 : len -= 16;
115 : 105 : DO16(buf);
116 : 105 : buf += 16;
117 : : }
118 [ + + ]: 8 : while (len--) {
119 : 7 : adler += *buf++;
120 : 7 : sum2 += adler;
121 : : }
122 : 1 : MOD(adler);
123 : 1 : MOD(sum2);
124 : : }
125 : :
126 : : /* return recombined sums */
127 : 4 : return adler | (sum2 << 16);
128 : : }
129 : :
130 : : #define MIN(a,b) (((a)<(b))?(a):(b))
131 : 0 : uint32_t adler32_last8(uint32_t adler, uint8_t *buf, size_t len)
132 : : {
133 : 0 : size_t min = MIN(len, 8);
134 : 0 : uint8_t *src = buf + (len-min);
135 : : #ifdef _ALIGN_MEM_ACCESS
136 : : uint64_t temp; // aligned
137 : : memcpy(&temp, src, min);
138 : : src = &temp;
139 : : #endif
140 : 0 : return adler32(adler, src, min);
141 : : }
142 : :
|