1 /*-
2 * Copyright (c) 2006, 2007
3 * Thorsten Glaser <tg@mirbsd.de>
4 * The adler32 algorithm is
5 * Copyright (C) 1995 Mark Adler
6 *
7 * Provided that these terms and disclaimer and all copyright notices
8 * are retained or reproduced in an accompanying document, permission
9 * is granted to deal in this work without restriction, including un-
10 * limited rights to use, publicly perform, distribute, sell, modify,
11 * merge, give away, or sublicence.
12 *
13 * Advertising materials mentioning features or use of this work must
14 * display the following acknowledgement:
15 * This product includes material provided by Thorsten Glaser.
16 *
17 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
18 * the utmost extent permitted by applicable law, neither express nor
19 * implied; without malicious intent or gross negligence. In no event
20 * may a licensor, author or contributor be held liable for indirect,
21 * direct, other damage, loss, or other issues arising in any way out
22 * of dealing in the work, even if advised of the possibility of such
23 * damage or existence of a defect, except proven that it results out
24 * of said person's immediate fault when using the work as intended.
25 */
26
27 #include <sys/param.h>
28 #include <adler32.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 __RCSID("$MirOS: src/lib/libc/hash/adh32.c,v 1.2 2007/08/19 12:03:13 tg Exp $");
33
34 void
ADLER32Init(ADLER32_CTX * ctx)35 ADLER32Init(ADLER32_CTX *ctx)
36 {
37 if (ctx != NULL)
38 *ctx = 1;
39 }
40
41 /*-
42 * See also:
43 * contrib/hosted/fwcf/adler.h
44 * src/lib/libc/hash/adh32.c
45 * src/kern/z/adler32s.c
46 * src/kern/z/adler32_i386.S
47 */
48 void
ADLER32Update(ADLER32_CTX * ctx,const uint8_t * buf,size_t len)49 ADLER32Update(ADLER32_CTX *ctx, const uint8_t *buf, size_t len)
50 {
51 uint32_t s1, s2, n;
52
53 if (ctx == NULL)
54 return;
55
56 s1 = (s2 = *ctx) & 0xFFFF;;
57 s2 >>= 16;
58
59 #define ADLER_BASE 65521 /* largest prime smaller than 65536 */
60 #define ADLER_NMAX 5552 /* largest n: 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
61 while (len) {
62 len -= (n = MIN(len, ADLER_NMAX));
63 while (n--) {
64 s1 += *buf++;
65 s2 += s1;
66 }
67 s1 %= ADLER_BASE;
68 s2 %= ADLER_BASE;
69 }
70
71 *ctx = s1 | (s2 << 16);
72 }
73
74 void
ADLER32Final(uint8_t * dst,ADLER32_CTX * ctx)75 ADLER32Final(uint8_t *dst, ADLER32_CTX *ctx)
76 {
77 uint32_t tmp = htobe32(*ctx);
78
79 if (dst)
80 memcpy(dst, &tmp, 4);
81 *ctx = 0;
82 }
83