-
Notifications
You must be signed in to change notification settings - Fork 1
/
hash_32.c
88 lines (75 loc) · 2.17 KB
/
hash_32.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "hash_32.h"
/*
* fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer
*
* input:
* buf - start of buffer to hash
* len - length of buffer in octets
* hval - previous hash value or 0 if first call
*
* returns:
* 32 bit hash as a static hash type
*
* NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval
* argument on the first call to either fnv_32_buf() or fnv_32_str().
*
* NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
* argument on the first call to either fnv_32_buf() or fnv_32_str().
*/
Fnv32_t
fnv_32_buf(void *buf, size_t len, Fnv32_t hval)
{
unsigned char *bp = (unsigned char *)buf; /* start of buffer */
unsigned char *be = bp + len; /* beyond end of buffer */
/*
* FNV-1 hash each octet in the buffer
*/
while (bp < be) {
/* multiply by the 32 bit FNV magic prime mod 2^32 */
#if defined(NO_FNV_GCC_OPTIMIZATION)
hval *= FNV_32_PRIME;
#else
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
#endif
/* xor the bottom with the current octet */
hval ^= (Fnv32_t)*bp++;
}
/* return our new hash value */
return hval;
}
/*
* fnv_32_str - perform a 32 bit Fowler/Noll/Vo hash on a string
*
* input:
* str - string to hash
* hval - previous hash value or 0 if first call
*
* returns:
* 32 bit hash as a static hash type
*
* NOTE: To use the 32 bit FNV-0 historic hash, use FNV0_32_INIT as the hval
* argument on the first call to either fnv_32_buf() or fnv_32_str().
*
* NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
* argument on the first call to either fnv_32_buf() or fnv_32_str().
*/
Fnv32_t
fnv_32_str(char *str, Fnv32_t hval)
{
unsigned char *s = (unsigned char *)str; /* unsigned string */
/*
* FNV-1 hash each octet in the buffer
*/
while (*s) {
/* multiply by the 32 bit FNV magic prime mod 2^32 */
#if defined(NO_FNV_GCC_OPTIMIZATION)
hval *= FNV_32_PRIME;
#else
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
#endif
/* xor the bottom with the current octet */
hval ^= (Fnv32_t)*s++;
}
/* return our new hash value */
return hval;
}