scclib
Stable Cloud Computing C++ Library
adler32.cc
1 #include <encode/adler32.h>
2 #include <system_error>
3 #include <zlib.h>
4 
5 using namespace scc::encode;
6 
7 uint32_t Adler32::update(const void* loc, int len)
8 {
9  if (loc == nullptr) throw std::runtime_error("adler32 update called with null");
10  if (len <= 0) throw std::runtime_error("adler32 update called with invalid len");
11 
12  m_val = adler32(m_val, static_cast<const Bytef*>(loc), len);
13  m_sz += len;
14  return m_val;
15 }
16 
17 /*
18  Using the recurrence relation where a(x, y) is low order and b(x, y)
19  is high order 16 bits of the checksum:
20 
21  xrem = value of data at x
22  xadd = value of data at y
23 
24  a(x+1,y+1) = (a(x,y) - xrem + xadd) MOD 65521
25  b(x+1,y+1) = (b(x,y) - N*xrem + a(x+1,y+1) - 1) MOD 65521
26 
27  where N=x-y+1 is the window size N
28 
29  To avoid calculating the modulus of a negative number,
30  can force the expression positive by adding a multiple of MOD
31  that ensures the value will be positive.
32 */
33 
34 #define MOD 65521
35 
36 uint32_t Adler32::rotate(unsigned char xrem, unsigned char xadd)
37 {
38  if (m_sz == 0) throw std::runtime_error("Cannot rotate with window size 0");
39 
40  uint32_t a = m_val & 0xffff;
41  a = (a - xrem + xadd + MOD) % MOD;
42  uint32_t b = (m_val >> 16) & 0xffff;
43  b = (b - m_sz*xrem + a - 1 + (m_sz*xrem/MOD+1)*MOD) % MOD;
44  m_val = (b << 16) | a;
45  return m_val;
46 }
47 
48 uint32_t Adler32::combine(const Adler32& add)
49 {
50  m_val = adler32_combine(m_val, add.m_val, add.m_sz);
51  return m_val;
52 }
Adler32 rolling checksum.
Adler-32 checksum allowing rolling calculation.
Definition: adler32.h:33
uint32_t rotate(unsigned char, unsigned char)
Update the checksum with next byte.
Definition: adler32.cc:36
uint32_t update(const void *, int)
Update the checksum with buffer contents.
Definition: adler32.cc:7