1/* $OpenLDAP$ */
2/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2000-2011 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 */
34void
35lutil_HASHInit( struct lutil_HASHContext *ctx )
36{
37	ctx->hash = HASH_OFFSET;
38}
39
40/*
41 * Update hash
42 */
43void
44lutil_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 */
68void
69lutil_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