You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hash.c 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * hash.c: hash functions
  20. */
  21. #include "includes.h"
  22. #include "hash.h"
  23. /* Robert Jenkins's 32 bit Mix Function */
  24. unsigned int
  25. inthash(unsigned int key)
  26. {
  27. key += (key << 12);
  28. key ^= (key >> 22);
  29. key += (key << 4);
  30. key ^= (key >> 9);
  31. key += (key << 10);
  32. key ^= (key >> 2);
  33. key += (key << 7);
  34. key ^= (key >> 12);
  35. return key;
  36. }
  37. /* Ripped 32bit Hash function
  38. *
  39. * Fowler/Noll/Vo hash
  40. *
  41. * See http://www.isthe.com/chongo/tech/comp/fnv/index.html
  42. * for more details as well as other forms of the FNV hash.
  43. *
  44. ***
  45. *
  46. * Use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
  47. * u_long hashval argument to fnv_32_buf().
  48. *
  49. ***
  50. *
  51. * Please do not copyright this code. This code is in the public domain.
  52. *
  53. * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  54. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  55. * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  56. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  57. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  58. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  59. * PERFORMANCE OF THIS SOFTWARE.
  60. *
  61. * By:
  62. * chongo <Landon Curt Noll> /\oo/\
  63. * http://www.isthe.com/chongo/
  64. * Share and Enjoy! :-)
  65. *
  66. * fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer
  67. * `hval' - previous hash value or 0 if first call
  68. * returns:
  69. * 32 bit hash as a static hash type
  70. */
  71. u_long
  72. fnv_32_buf(void *buf, size_t len, u_long hval)
  73. {
  74. u_char *bp = (u_char *) buf; /* start of buffer */
  75. u_char *be = bp + len; /* beyond end of buffer */
  76. /*
  77. * FNV-1 hash each octet in the buffer
  78. */
  79. while (bp < be) {
  80. /* multiply by the 32 bit FNV magic prime mod 2^32 */
  81. hval +=
  82. (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) +
  83. (hval << 24);
  84. /* xor the bottom with the current octet */
  85. hval ^= (u_long) * bp++;
  86. }
  87. /* return our new hash value */
  88. return hval;
  89. }
  90. /*
  91. * Ripped from glibc.
  92. * This is the hashing function specified by the ELF ABI. In the
  93. * first five operations no overflow is possible so we optimized it a
  94. * bit.
  95. */
  96. unsigned int
  97. dl_elf_hash(const unsigned char *name)
  98. {
  99. unsigned long int hash = 0;
  100. if (*name != '\0') {
  101. hash = *name++;
  102. if (*name != '\0') {
  103. hash = (hash << 4) + *name++;
  104. if (*name != '\0') {
  105. hash = (hash << 4) + *name++;
  106. if (*name != '\0') {
  107. hash = (hash << 4) + *name++;
  108. if (*name != '\0') {
  109. hash = (hash << 4) + *name++;
  110. while (*name != '\0') {
  111. unsigned long int hi;
  112. hash = (hash << 4) + *name++;
  113. hi = hash & 0xf0000000;
  114. /* The algorithm specified in the ELF ABI is as
  115. follows:
  116. if (hi != 0)
  117. hash ^= hi >> 24;
  118. hash &= ~hi;
  119. But the following is equivalent and a lot
  120. faster, especially on modern processors. */
  121. hash ^= hi;
  122. hash ^= hi >> 24;
  123. }
  124. }
  125. }
  126. }
  127. }
  128. }
  129. return hash;
  130. }
  131. /*
  132. * hash_time: As the name says: hash time!
  133. * This function generates the hash of the timeval struct which refer
  134. * to the current time.
  135. * If h_sec or h_usec are not null, it stores in them respectively the hash of
  136. * the second and the microsecond.
  137. */
  138. int
  139. hash_time(int *h_sec, int *h_usec)
  140. {
  141. struct timeval t;
  142. char str[sizeof(struct timeval) + 1];
  143. u_int elf_hash;
  144. gettimeofday(&t, 0);
  145. memcpy(str, &t, sizeof(struct timeval));
  146. str[sizeof(struct timeval)] = 0;
  147. elf_hash = dl_elf_hash((u_char *) str);
  148. if (h_sec)
  149. *h_sec = inthash(t.tv_sec);
  150. if (h_usec)
  151. *h_usec = inthash(t.tv_usec);
  152. return inthash(elf_hash);
  153. }