1.\" $MirOS: src/lib/libc/hash/adler32.3,v 1.3 2009/11/22 18:23:41 tg Exp $
2.\"-
3.\" Copyright (c) 2007, 2009
4.\"	Thorsten Glaser <tg@mirbsd.org>
5.\"
6.\" Provided that these terms and disclaimer and all copyright notices
7.\" are retained or reproduced in an accompanying document, permission
8.\" is granted to deal in this work without restriction, including un-
9.\" limited rights to use, publicly perform, distribute, sell, modify,
10.\" merge, give away, or sublicence.
11.\"
12.\" This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
13.\" the utmost extent permitted by applicable law, neither express nor
14.\" implied; without malicious intent or gross negligence. In no event
15.\" may a licensor, author or contributor be held liable for indirect,
16.\" direct, other damage, loss, or other issues arising in any way out
17.\" of dealing in the work, even if advised of the possibility of such
18.\" damage or existence of a defect, except proven that it results out
19.\" of said person's immediate fault when using the work as intended.
20.\"-
21.\" Try to make GNU groff and AT&T nroff more compatible
22.\" * ` generates ‘ in gnroff, so use \`
23.\" * ' generates ’ in gnroff, \' generates ´, so use \*(aq
24.\" * - generates ‐ in gnroff, \- generates −, so .tr it to -
25.\"   thus use - for hyphens and \- for minus signs and option dashes
26.\" * ~ is size-reduced and placed atop in groff, so use \*(TI
27.\" * ^ is size-reduced and placed atop in groff, so use \*(ha
28.\" * \(en does not work in nroff, so use \*(en
29.\" The section after the "doc" macropackage has been loaded contains
30.\" additional code to convene between the UCB mdoc macropackage (and
31.\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage.
32.\"
33.ie \n(.g \{\
34.	if \*[.T]ascii .tr \-\N'45'
35.	if \*[.T]latin1 .tr \-\N'45'
36.	if \*[.T]utf8 .tr \-\N'45'
37.	ds <= \[<=]
38.	ds >= \[>=]
39.	ds Rq \[rq]
40.	ds Lq \[lq]
41.	ds sL \(aq
42.	ds sR \(aq
43.	if \*[.T]utf8 .ds sL `
44.	if \*[.T]ps .ds sL `
45.	if \*[.T]utf8 .ds sR '
46.	if \*[.T]ps .ds sR '
47.	ds aq \(aq
48.	ds TI \(ti
49.	ds ha \(ha
50.	ds en \(en
51.\}
52.el \{\
53.	ds aq '
54.	ds TI ~
55.	ds ha ^
56.	ds en \(em
57.\}
58.\"
59.\" Implement .Dd with the Mdocdate RCS keyword
60.\"
61.rn Dd xD
62.de Dd
63.ie \\$1$Mdocdate: \{\
64.	xD \\$2 \\$3, \\$4
65.\}
66.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
67..
68.\"
69.\" .Dd must come before definition of .Mx, because when called
70.\" with -mandoc, it might implement .Mx itself, but we want to
71.\" use our own definition. And .Dd must come *first*, always.
72.\"
73.Dd $Mdocdate: November 22 2009 $
74.\"
75.\" Check which macro package we use
76.\"
77.ie \n(.g \{\
78.	ie d volume-ds-1 .ds tT gnu
79.	el .ds tT bsd
80.\}
81.el .ds tT ucb
82.\"
83.\" Implement .Mx (MirBSD)
84.\"
85.ie "\*(tT"gnu" \{\
86.	eo
87.	de Mx
88.	nr curr-font \n[.f]
89.	nr curr-size \n[.ps]
90.	ds str-Mx \f[\n[curr-font]]\s[\n[curr-size]u]
91.	ds str-Mx1 \*[Tn-font-size]\%MirOS\*[str-Mx]
92.	if !\n[arg-limit] \
93.	if \n[.$] \{\
94.	ds macro-name Mx
95.	parse-args \$@
96.	\}
97.	if (\n[arg-limit] > \n[arg-ptr]) \{\
98.	nr arg-ptr +1
99.	ie (\n[type\n[arg-ptr]] == 2) \
100.	as str-Mx1 \~\*[arg\n[arg-ptr]]
101.	el \
102.	nr arg-ptr -1
103.	\}
104.	ds arg\n[arg-ptr] "\*[str-Mx1]
105.	nr type\n[arg-ptr] 2
106.	ds space\n[arg-ptr] "\*[space]
107.	nr num-args (\n[arg-limit] - \n[arg-ptr])
108.	nr arg-limit \n[arg-ptr]
109.	if \n[num-args] \
110.	parse-space-vector
111.	print-recursive
112..
113.	ec
114.	ds sP \s0
115.	ds tN \*[Tn-font-size]
116.\}
117.el \{\
118.	de Mx
119.	nr cF \\n(.f
120.	nr cZ \\n(.s
121.	ds aa \&\f\\n(cF\s\\n(cZ
122.	if \\n(aC==0 \{\
123.		ie \\n(.$==0 \&MirOS\\*(aa
124.		el .aV \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
125.	\}
126.	if \\n(aC>\\n(aP \{\
127.		nr aP \\n(aP+1
128.		ie \\n(C\\n(aP==2 \{\
129.			as b1 \&MirOS\ #\&\\*(A\\n(aP\\*(aa
130.			ie \\n(aC>\\n(aP \{\
131.				nr aP \\n(aP+1
132.				nR
133.			\}
134.			el .aZ
135.		\}
136.		el \{\
137.			as b1 \&MirOS\\*(aa
138.			nR
139.		\}
140.	\}
141..
142.\}
143.\"-
144.Dt ADLER32 3
145.Os
146.Sh NAME
147.Nm ADLER32Init ,
148.Nm ADLER32Update ,
149.Nm ADLER32Final ,
150.Nm ADLER32End ,
151.Nm ADLER32File ,
152.Nm ADLER32FileChunk ,
153.Nm ADLER32Data
154.Nd calculate the "ADLER32" checksum
155.Sh SYNOPSIS
156.Fd #include <sys/types.h>
157.Fd #include <adler32.h>
158.Ft void
159.Fn ADLER32Init "ADLER32_CTX *ctx"
160.Ft void
161.Fn ADLER32Update "ADLER32_CTX *ctx" "const uint8_t *data" "size_t noctets"
162.Ft void
163.Fn ADLER32Final "uint8_t digest[ADLER32_DIGEST_LENGTH]" "ADLER32_CTX *ctx"
164.Ft "char *"
165.Fn ADLER32End "ADLER32_CTX *ctx" "char *digest"
166.Ft "char *"
167.Fn ADLER32File "const char *filename" "char *digest"
168.Ft "char *"
169.Fn ADLER32FileChunk "const char *filename" "char *digest" "off_t offset" "off_t length"
170.Ft "char *"
171.Fn ADLER32Data "const uint8_t *data" "size_t len" "char *digest"
172.Sh DESCRIPTION
173The ADLER32 functions implement the 32-bit ADLER32 cyclic redundancy checksum.
174They share a similar API to the
175.Xr md5 3
176interface.
177.\"XXX algorithm description - take from compress(3) or so
178.Pp
179The
180.Fn ADLER32Init
181function initialises a ADLER32_CTX context for use with
182.Fn ADLER32Update
183and
184.Fn ADLER32Final .
185The
186.Fn ADLER32Update
187function adds (condenses)
188.Ar data
189of length
190.Ar noctets
191to the context.
192.Fn ADLER32Final
193is called after processing and stores a message digest in the
194.Ar digest
195parameter.
196.Pp
197For a description of the other functions, please refer e\.g\. the
198.Xr rmd160 3
199manual page.
200.Sh EXAMPLES
201The follow code fragment will calculate the checksum for
202the string
203.Dq abc ,
204which is
205.Dq 024D0127 .
206.Bd -literal -offset indent
207ADLER32_CTX context;
208uint8_t result[ADLER32_DIGEST_LENGTH];
209const char buf[] = "abc";
210size_t n = strlen(buf);
211
212ADLER32Init(&context);
213ADLER32Update(&context, buf, n);
214ADLER32Final(result, &context);
215
216/* print the digest as one long sedecimal value */
217printf("0x");
218for (n = 0; n \*(Lt ADLER32_DIGEST_LENGTH; n++)
219	printf("%02X", result[n]);
220putchar(\*(aq\en\*(aq);
221.Ed
222.Pp
223Alternately, the helper functions could be used in the following way:
224.Bd -literal -offset indent
225ADLER32_CTX context;
226uint8_t output[ADLER32_DIGEST_STRING_LENGTH];
227const char buf[] = "abc";
228
229printf("0x%s\en", ADLER32Data(buf, strlen(buf), output));
230.Ed
231.Sh SEE ALSO
232.Xr cksum 1 ,
233.Xr compress 3 ,
234.Xr md4 3 ,
235.Xr md5 3 ,
236.Xr rmd160 3 ,
237.Xr sfv 3 ,
238.Xr sha1 3 ,
239.Xr sha2 3 ,
240.Xr suma 3 ,
241.Xr tiger 3 ,
242.Xr whirlpool 3
243.Sh HISTORY
244The ADLER32 functions appeared in
245.Mx 10 .
246.Sh AUTHORS
247This implementation of ADLER32 was written by
248.An Thorsten Glaser Aq tg@mirbsd.de
249as a size-optimised version of the zlib Adler-32 checksum.
250.Pp
251The
252.Fn ADLER32End ,
253.Fn ADLER32File ,
254.Fn ADLER32FileChunk ,
255and
256.Fn ADLER32Data
257helper functions are derived from code written by Poul-Henning Kamp.
258