-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhash.c
68 lines (60 loc) · 2.38 KB
/
hash.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
/* Copyright 2014 Andrew Bates
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This hashing mechanism and related functions were adapted from
* code by Robert J. Jenkins Jr.
* See: http://burtleburtle.net/bob/hash/evahash.html
*/
#include "hash.h"
/* The whole new hash function */
hash_word_t hash(ipv4_tuple *tuple, hash_word_t initval) {
int length = sizeof(ipv4_tuple);
register hash_byte_t *k = (void *)tuple;
register hash_word_t a,b,c; /* the internal state */
hash_word_t len; /* how many key bytes still need mixing */
/* Set up the internal state */
len = length;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = initval; /* variable initialization of internal state */
/*---------------------------------------- handle most of the key */
while (len >= 12) {
a=a+(k[0]+((hash_word_t)k[1]<<8)+((hash_word_t)k[2]<<16) +((hash_word_t)k[3]<<24));
b=b+(k[4]+((hash_word_t)k[5]<<8)+((hash_word_t)k[6]<<16) +((hash_word_t)k[7]<<24));
c=c+(k[8]+((hash_word_t)k[9]<<8)+((hash_word_t)k[10]<<16)+((hash_word_t)k[11]<<24));
mix(a,b,c);
k = k+12; len = len-12;
}
/*------------------------------------- handle the last 11 bytes */
c = c+length;
/* all the case statements fall through */
switch(len) {
case 11: c=c+((hash_word_t)k[10]<<24);
case 10: c=c+((hash_word_t)k[9]<<16);
case 9 : c=c+((hash_word_t)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b=b+((hash_word_t)k[7]<<24);
case 7 : b=b+((hash_word_t)k[6]<<16);
case 6 : b=b+((hash_word_t)k[5]<<8);
case 5 : b=b+k[4];
case 4 : a=a+((hash_word_t)k[3]<<24);
case 3 : a=a+((hash_word_t)k[2]<<16);
case 2 : a=a+((hash_word_t)k[1]<<8);
case 1 : a=a+k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
/*-------------------------------------------- report the result */
return c;
}