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