xref: /inferno-os/os/boot/libflate/adler.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "lib9.h"
2*74a4d8c2SCharles.Forsyth #include <flate.h>
3*74a4d8c2SCharles.Forsyth 
4*74a4d8c2SCharles.Forsyth enum
5*74a4d8c2SCharles.Forsyth {
6*74a4d8c2SCharles.Forsyth 	ADLERITERS	= 5552,	/* max iters before can overflow 32 bits */
7*74a4d8c2SCharles.Forsyth 	ADLERBASE	= 65521 /* largest prime smaller than 65536 */
8*74a4d8c2SCharles.Forsyth };
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth ulong
adler32(ulong adler,void * vbuf,int n)11*74a4d8c2SCharles.Forsyth adler32(ulong adler, void *vbuf, int n)
12*74a4d8c2SCharles.Forsyth {
13*74a4d8c2SCharles.Forsyth 	ulong s1, s2;
14*74a4d8c2SCharles.Forsyth 	uchar *buf, *ebuf;
15*74a4d8c2SCharles.Forsyth 	int m;
16*74a4d8c2SCharles.Forsyth 
17*74a4d8c2SCharles.Forsyth 	buf = vbuf;
18*74a4d8c2SCharles.Forsyth 	s1 = adler & 0xffff;
19*74a4d8c2SCharles.Forsyth 	s2 = (adler >> 16) & 0xffff;
20*74a4d8c2SCharles.Forsyth 	for(; n >= 16; n -= m){
21*74a4d8c2SCharles.Forsyth 		m = n;
22*74a4d8c2SCharles.Forsyth 		if(m > ADLERITERS)
23*74a4d8c2SCharles.Forsyth 			m = ADLERITERS;
24*74a4d8c2SCharles.Forsyth 		m &= ~15;
25*74a4d8c2SCharles.Forsyth 		for(ebuf = buf + m; buf < ebuf; buf += 16){
26*74a4d8c2SCharles.Forsyth 			s1 += buf[0];
27*74a4d8c2SCharles.Forsyth 			s2 += s1;
28*74a4d8c2SCharles.Forsyth 			s1 += buf[1];
29*74a4d8c2SCharles.Forsyth 			s2 += s1;
30*74a4d8c2SCharles.Forsyth 			s1 += buf[2];
31*74a4d8c2SCharles.Forsyth 			s2 += s1;
32*74a4d8c2SCharles.Forsyth 			s1 += buf[3];
33*74a4d8c2SCharles.Forsyth 			s2 += s1;
34*74a4d8c2SCharles.Forsyth 			s1 += buf[4];
35*74a4d8c2SCharles.Forsyth 			s2 += s1;
36*74a4d8c2SCharles.Forsyth 			s1 += buf[5];
37*74a4d8c2SCharles.Forsyth 			s2 += s1;
38*74a4d8c2SCharles.Forsyth 			s1 += buf[6];
39*74a4d8c2SCharles.Forsyth 			s2 += s1;
40*74a4d8c2SCharles.Forsyth 			s1 += buf[7];
41*74a4d8c2SCharles.Forsyth 			s2 += s1;
42*74a4d8c2SCharles.Forsyth 			s1 += buf[8];
43*74a4d8c2SCharles.Forsyth 			s2 += s1;
44*74a4d8c2SCharles.Forsyth 			s1 += buf[9];
45*74a4d8c2SCharles.Forsyth 			s2 += s1;
46*74a4d8c2SCharles.Forsyth 			s1 += buf[10];
47*74a4d8c2SCharles.Forsyth 			s2 += s1;
48*74a4d8c2SCharles.Forsyth 			s1 += buf[11];
49*74a4d8c2SCharles.Forsyth 			s2 += s1;
50*74a4d8c2SCharles.Forsyth 			s1 += buf[12];
51*74a4d8c2SCharles.Forsyth 			s2 += s1;
52*74a4d8c2SCharles.Forsyth 			s1 += buf[13];
53*74a4d8c2SCharles.Forsyth 			s2 += s1;
54*74a4d8c2SCharles.Forsyth 			s1 += buf[14];
55*74a4d8c2SCharles.Forsyth 			s2 += s1;
56*74a4d8c2SCharles.Forsyth 			s1 += buf[15];
57*74a4d8c2SCharles.Forsyth 			s2 += s1;
58*74a4d8c2SCharles.Forsyth 		}
59*74a4d8c2SCharles.Forsyth 		s1 %= ADLERBASE;
60*74a4d8c2SCharles.Forsyth 		s2 %= ADLERBASE;
61*74a4d8c2SCharles.Forsyth 	}
62*74a4d8c2SCharles.Forsyth 	if(n){
63*74a4d8c2SCharles.Forsyth 		for(ebuf = buf + n; buf < ebuf; buf++){
64*74a4d8c2SCharles.Forsyth 			s1 += buf[0];
65*74a4d8c2SCharles.Forsyth 			s2 += s1;
66*74a4d8c2SCharles.Forsyth 		}
67*74a4d8c2SCharles.Forsyth 		s1 %= ADLERBASE;
68*74a4d8c2SCharles.Forsyth 		s2 %= ADLERBASE;
69*74a4d8c2SCharles.Forsyth 	}
70*74a4d8c2SCharles.Forsyth 	return (s2 << 16) + s1;
71*74a4d8c2SCharles.Forsyth }
72