1 #include <cstdint>
2 #include "Common/Data/Hash/Hash.h"
3 
4 namespace hash {
5 
6 // Implementation from Wikipedia
7 #define MOD_ADLER 65521
8 // data: Pointer to the data to be summed; len is in bytes
Adler32(const uint8_t * data,size_t len)9 uint32_t Adler32(const uint8_t *data, size_t len) {
10 	uint32_t a = 1, b = 0;
11 	while (len) {
12 		size_t tlen = len > 5550 ? 5550 : len;
13 		len -= tlen;
14 		do {
15 			a += *data++;
16 			b += a;
17 		} while (--tlen);
18 
19 		a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER);
20 		b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
21 	}
22 
23 	// It can be shown that a <= 0x1013a here, so a single subtract will do.
24 	if (a >= MOD_ADLER) {
25 		a -= MOD_ADLER;
26 	}
27 
28 	// It can be shown that b can reach 0xfff87 here.
29 	b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER);
30 
31 	if (b >= MOD_ADLER) {
32 		b -= MOD_ADLER;
33 	}
34 	return (b << 16) | a;
35 }
36 
37 }  // namespace hash
38