9
0
Fork 0
This repository has been archived on 2022-06-17. You can view files and clone it, but cannot push or open issues or pull requests.
openggsn/lib/lookup.c

92 lines
2.4 KiB
C
Executable File

/*
* Hash lookup function.
* Copyright (C) 2003, 2004 Mondru AB.
*
* The contents of this file may be used under the terms of the GNU
* General Public License Version 2, provided that the above copyright
* notice and this permission notice is included in all copies or
* substantial portions of the software.
*
*/
/**
* lookup()
* Generates a 32 bit hash.
* Based on public domain code by Bob Jenkins
* It should be one of the best hash functions around in terms of both
* statistical properties and speed. It is NOT recommended for cryptographic
* purposes.
**/
unsigned long int lookup(k, length, level)
register unsigned char *k; /* the key */
register unsigned long int length; /* the length of the key */
register unsigned long int level; /* the previous hash, or an arbitrary value */
{
#define mix(a,b,c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
register unsigned long int a, b, c, len;
/* Set up the internal state */
len = length;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = level; /* the previous hash value */
/*---------------------------------------- handle most of the key */
while (len >= 12) {
a += (k[0] + ((ub4) k[1] << 8) + ((ub4) k[2] << 16) +
((ub4) k[3] << 24));
b += (k[4] + ((ub4) k[5] << 8) + ((ub4) k[6] << 16) +
((ub4) k[7] << 24));
c += (k[8] + ((ub4) k[9] << 8) + ((ub4) k[10] << 16) +
((ub4) k[11] << 24));
mix(a, b, c);
k += 12;
len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
switch (len) { /* all the case statements fall through */
case 11:
c += ((ub4) k[10] << 24);
case 10:
c += ((ub4) k[9] << 16);
case 9:
c += ((ub4) k[8] << 8);
/* the first byte of c is reserved for the length */
case 8:
b += ((ub4) k[7] << 24);
case 7:
b += ((ub4) k[6] << 16);
case 6:
b += ((ub4) k[5] << 8);
case 5:
b += k[4];
case 4:
a += ((ub4) k[3] << 24);
case 3:
a += ((ub4) k[2] << 16);
case 2:
a += ((ub4) k[1] << 8);
case 1:
a += k[0];
/* case 0: nothing left to add */
}
mix(a, b, c);
/*-------------------------------------------- report the result */
return c;
}