1 // adler32.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "adler32.h"
5 
NAMESPACE_BEGIN(CryptoPP)6 NAMESPACE_BEGIN(CryptoPP)
7 
8 void Adler32::Update(const byte *input, size_t length)
9 {
10 	const unsigned long BASE = 65521;
11 
12 	unsigned long s1 = m_s1;
13 	unsigned long s2 = m_s2;
14 
15 	if (length % 8 != 0)
16 	{
17 		do
18 		{
19 			s1 += *input++;
20 			s2 += s1;
21 			length--;
22 		} while (length % 8 != 0);
23 
24 		if (s1 >= BASE)
25 			s1 -= BASE;
26 		s2 %= BASE;
27 	}
28 
29 	while (length > 0)
30 	{
31 		s1 += input[0]; s2 += s1;
32 		s1 += input[1]; s2 += s1;
33 		s1 += input[2]; s2 += s1;
34 		s1 += input[3]; s2 += s1;
35 		s1 += input[4]; s2 += s1;
36 		s1 += input[5]; s2 += s1;
37 		s1 += input[6]; s2 += s1;
38 		s1 += input[7]; s2 += s1;
39 
40 		length -= 8;
41 		input += 8;
42 
43 		if (s1 >= BASE)
44 			s1 -= BASE;
45 		if (length % 0x8000 == 0)
46 			s2 %= BASE;
47 	}
48 
49 	CRYPTOPP_ASSERT(s1 < BASE);
50 	CRYPTOPP_ASSERT(s2 < BASE);
51 
52 	m_s1 = (word16)s1;
53 	m_s2 = (word16)s2;
54 }
55 
TruncatedFinal(byte * hash,size_t size)56 void Adler32::TruncatedFinal(byte *hash, size_t size)
57 {
58 	ThrowIfInvalidTruncatedSize(size);
59 
60 	switch (size)
61 	{
62 	default:
63 		hash[3] = byte(m_s1);
64 		// fall through
65 	case 3:
66 		hash[2] = byte(m_s1 >> 8);
67 		// fall through
68 	case 2:
69 		hash[1] = byte(m_s2);
70 		// fall through
71 	case 1:
72 		hash[0] = byte(m_s2 >> 8);
73 		// fall through
74 	case 0:
75 		;
76 		// fall through
77 	}
78 
79 	Reset();
80 }
81 
82 NAMESPACE_END
83