xref: /netbsd-src/external/bsd/openldap/dist/libraries/liblutil/hash.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: hash.c,v 1.2 2020/08/11 13:15:39 christos Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 2000-2020 The OpenLDAP Foundation.
7  * Portions Copyright 2000-2003 Kurt D. Zeilenga.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
14  * A copy of this license is available in the file LICENSE in the
15  * top-level directory of the distribution or, alternatively, at
16  * <http://www.OpenLDAP.org/license.html>.
17  */
18 
19 /* This implements the Fowler / Noll / Vo (FNV-1) hash algorithm.
20  * A summary of the algorithm can be found at:
21  *   http://www.isthe.com/chongo/tech/comp/fnv/index.html
22  */
23 
24 #include <sys/cdefs.h>
25 __RCSID("$NetBSD: hash.c,v 1.2 2020/08/11 13:15:39 christos Exp $");
26 
27 #include "portable.h"
28 
29 #include <lutil_hash.h>
30 
31 /* offset and prime for 32-bit FNV-1 */
32 #define HASH_OFFSET	0x811c9dc5U
33 #define HASH_PRIME	16777619
34 
35 
36 /*
37  * Initialize context
38  */
39 void
40 lutil_HASHInit( struct lutil_HASHContext *ctx )
41 {
42 	ctx->hash = HASH_OFFSET;
43 }
44 
45 /*
46  * Update hash
47  */
48 void
49 lutil_HASHUpdate(
50     struct lutil_HASHContext	*ctx,
51     const unsigned char		*buf,
52     ber_len_t		len )
53 {
54 	const unsigned char *p, *e;
55 	ber_uint_t h;
56 
57 	p = buf;
58 	e = &buf[len];
59 
60 	h = ctx->hash;
61 
62 	while( p < e ) {
63 		h *= HASH_PRIME;
64 		h ^= *p++;
65 	}
66 
67 	ctx->hash = h;
68 }
69 
70 /*
71  * Save hash
72  */
73 void
74 lutil_HASHFinal( unsigned char *digest, struct lutil_HASHContext *ctx )
75 {
76 	ber_uint_t h = ctx->hash;
77 
78 	digest[0] = h & 0xffU;
79 	digest[1] = (h>>8) & 0xffU;
80 	digest[2] = (h>>16) & 0xffU;
81 	digest[3] = (h>>24) & 0xffU;
82 }
83