mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
177 lines
3.9 KiB
C
177 lines
3.9 KiB
C
/**
|
|
* This file contains some simple hash function
|
|
*
|
|
* Copyright (C) 2013 Freie Universität Berlin
|
|
*
|
|
* This file subject to the terms and conditions of the GNU Lesser General
|
|
* Public License. See the file LICENSE in the top level directory for more
|
|
* details.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* @autor Jason Linehan <patientulysses@gmail.com>
|
|
* @author Freie Universität Berlin, Computer Systems & Telematics
|
|
* @author Christian Mehlis <mehlis@inf.fu-berlin.de>
|
|
*/
|
|
|
|
/**
|
|
* djb2_hash
|
|
*
|
|
* HISTORY
|
|
* This algorithm (k=33) was first reported by Dan Bernstein many years
|
|
* ago in comp.lang.c. Another version of this algorithm (now favored by
|
|
* bernstein) uses XOR:
|
|
*
|
|
* hash(i) = hash(i - 1) * 33 ^ str[i];
|
|
*
|
|
* The magic of number 33 (why it works better than many other constants,
|
|
* prime or not) has never been adequately explained.
|
|
*/
|
|
static inline unsigned long djb2_hash(const char *str)
|
|
{
|
|
unsigned long hash;
|
|
int c;
|
|
|
|
hash = 5381;
|
|
|
|
while ((c = (unsigned char) * str++)) {
|
|
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
/**
|
|
* sdbm_hash
|
|
*
|
|
* HISTORY
|
|
* This algorithm was created for sdbm (a public-domain reimplementation
|
|
* of ndbm) database library. It was found to do well in scrambling bits,
|
|
* causing better distribution of the keys and fewer splits. it also
|
|
* happens to be a good general hashing function with good distribution.
|
|
*
|
|
* The actual function is
|
|
*
|
|
* hash(i) = hash(i - 1) * 65599 + str[i];
|
|
*
|
|
* What is included below is the faster version used in gawk. [there is
|
|
* even a faster, duff-device version] the magic constant 65599 was picked
|
|
* out of thin air while experimenting with different constants, and turns
|
|
* out to be a prime. this is one of the algorithms used in berkeley db
|
|
* (see sleepycat) and elsewhere.
|
|
*
|
|
*/
|
|
static inline unsigned long sdbm_hash(const char *str)
|
|
{
|
|
unsigned long hash;
|
|
int c;
|
|
|
|
hash = 0;
|
|
|
|
while ((c = (unsigned char) * str++)) {
|
|
hash = c + (hash << 6) + (hash << 16) - hash;
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
/**
|
|
* lose lose
|
|
*
|
|
* HISTORY
|
|
* This hash function appeared in K&R (1st ed) but at least the reader
|
|
* was warned:
|
|
*
|
|
* "This is not the best possible algorithm, but it has the merit
|
|
* of extreme simplicity."
|
|
*
|
|
* This is an understatement. It is a terrible hashing algorithm, and it
|
|
* could have been much better without sacrificing its "extreme simplicity."
|
|
* [see the second edition!]
|
|
*
|
|
* Many C programmers use this function without actually testing it, or
|
|
* checking something like Knuth's Sorting and Searching, so it stuck.
|
|
* It is now found mixed with otherwise respectable code, eg. cnews. sigh.
|
|
* [see also: tpop]
|
|
*/
|
|
static inline unsigned long kr_hash(const char *str)
|
|
{
|
|
unsigned int hash;
|
|
unsigned int c;
|
|
|
|
hash = 0;
|
|
|
|
while ((c = (unsigned char) * str++)) {
|
|
hash += c;
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
/**
|
|
* sax_hash
|
|
*
|
|
* Shift, Add, XOR
|
|
*/
|
|
static inline unsigned int sax_hash(const char *key)
|
|
{
|
|
unsigned int h;
|
|
|
|
h = 0;
|
|
|
|
while (*key) {
|
|
h ^= (h << 5) + (h >> 2) + (unsigned char) * key++;
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
|
|
/**
|
|
* dek_hash
|
|
*
|
|
* HISTORY
|
|
* Proposed by Donald E. Knuth in The Art Of Computer Programming Vol. 3,
|
|
* under the topic of "Sorting and Search", Chapter 6.4.
|
|
*/
|
|
static inline unsigned int dek_hash(const char *str, unsigned int len)
|
|
{
|
|
unsigned int hash;
|
|
unsigned int c;
|
|
|
|
hash = len;
|
|
c = 0;
|
|
|
|
while ((c = (unsigned int) * str++)) {
|
|
hash = ((hash << 5) ^ (hash >> 27)) ^ (c);
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
|
|
/**
|
|
* fnv_hash
|
|
*
|
|
* NOTE
|
|
* For a more fully featured and modern version of this hash, see fnv32.c
|
|
*/
|
|
static inline unsigned int fnv_hash(const char *str)
|
|
{
|
|
#define FNV_PRIME 0x811C9DC5
|
|
unsigned int hash;
|
|
unsigned int c;
|
|
|
|
hash = 0;
|
|
c = 0;
|
|
|
|
while ((c = (unsigned int) * str++)) {
|
|
hash *= FNV_PRIME;
|
|
hash ^= (c);
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|