fnv.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * fnv - Fowler/Noll/Vo- hash code
  3. *
  4. * @(#) $Revision: 5.4 $
  5. * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $
  6. * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $
  7. *
  8. ***
  9. *
  10. * Fowler/Noll/Vo- hash
  11. *
  12. * The basis of this hash algorithm was taken from an idea sent
  13. * as reviewer comments to the IEEE POSIX P1003.2 committee by:
  14. *
  15. * Phong Vo (http://www.research.att.com/info/kpv/)
  16. * Glenn Fowler (http://www.research.att.com/~gsf/)
  17. *
  18. * In a subsequent ballot round:
  19. *
  20. * Landon Curt Noll (http://www.isthe.com/chongo/)
  21. *
  22. * improved on their algorithm. Some people tried this hash
  23. * and found that it worked rather well. In an EMail message
  24. * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
  25. *
  26. * FNV hashes are designed to be fast while maintaining a low
  27. * collision rate. The FNV speed allows one to quickly hash lots
  28. * of data while maintaining a reasonable collision rate. See:
  29. *
  30. * http://www.isthe.com/chongo/tech/comp/fnv/index.html
  31. *
  32. * for more details as well as other forms of the FNV hash.
  33. *
  34. ***
  35. *
  36. * NOTE: The FNV-0 historic hash is not recommended. One should use
  37. * the FNV-1 hash instead.
  38. *
  39. * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the
  40. * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
  41. *
  42. * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
  43. * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  44. *
  45. * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
  46. * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
  47. *
  48. * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
  49. * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  50. *
  51. * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
  52. * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
  53. *
  54. * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the
  55. * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str().
  56. *
  57. ***
  58. *
  59. * Please do not copyright this code. This code is in the public domain.
  60. *
  61. * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  62. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  63. * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  64. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  65. * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  66. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  67. * PERFORMANCE OF THIS SOFTWARE.
  68. *
  69. * By:
  70. * chongo <Landon Curt Noll> /\oo/\
  71. * http://www.isthe.com/chongo/
  72. *
  73. * Share and Enjoy! :-)
  74. */
  75. #if !defined(__FNV_H__)
  76. #define __FNV_H__
  77. #include <sys/types.h>
  78. #define FNV_VERSION "5.0.2" /* @(#) FNV Version */
  79. /*
  80. * 32 bit FNV-0 hash type
  81. */
  82. typedef u_int32_t Fnv32_t;
  83. /*
  84. * 32 bit FNV-0 zero initial basis
  85. *
  86. * This historic hash is not recommended. One should use
  87. * the FNV-1 hash and initial basis instead.
  88. */
  89. #define FNV0_32_INIT ((Fnv32_t)0)
  90. /*
  91. * 32 bit FNV-1 and FNV-1a non-zero initial basis
  92. *
  93. * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
  94. *
  95. * chongo <Landon Curt Noll> /\../\
  96. *
  97. * NOTE: The \'s above are not back-slashing escape characters.
  98. * They are literal ASCII backslash 0x5c characters.
  99. *
  100. * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
  101. */
  102. #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5)
  103. #define FNV1_32A_INIT FNV1_32_INIT
  104. /*
  105. * determine how 64 bit unsigned values are represented
  106. */
  107. #include "longlong.h"
  108. /*
  109. * 64 bit FNV-0 hash
  110. */
  111. #if defined(HAVE_64BIT_LONG_LONG)
  112. typedef u_int64_t Fnv64_t;
  113. #else /* HAVE_64BIT_LONG_LONG */
  114. typedef struct {
  115. u_int32_t w32[2]; /* w32[0] is low order, w32[1] is high order word */
  116. } Fnv64_t;
  117. #endif /* HAVE_64BIT_LONG_LONG */
  118. /*
  119. * 64 bit FNV-0 zero initial basis
  120. *
  121. * This historic hash is not recommended. One should use
  122. * the FNV-1 hash and initial basis instead.
  123. */
  124. #if defined(HAVE_64BIT_LONG_LONG)
  125. #define FNV0_64_INIT ((Fnv64_t)0)
  126. #else /* HAVE_64BIT_LONG_LONG */
  127. extern const Fnv64_t fnv0_64_init;
  128. #define FNV0_64_INIT (fnv0_64_init)
  129. #endif /* HAVE_64BIT_LONG_LONG */
  130. /*
  131. * 64 bit FNV-1 non-zero initial basis
  132. *
  133. * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
  134. *
  135. * chongo <Landon Curt Noll> /\../\
  136. *
  137. * NOTE: The \'s above are not back-slashing escape characters.
  138. * They are literal ASCII backslash 0x5c characters.
  139. *
  140. * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
  141. */
  142. #if defined(HAVE_64BIT_LONG_LONG)
  143. #define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL)
  144. #define FNV1A_64_INIT FNV1_64_INIT
  145. #else /* HAVE_64BIT_LONG_LONG */
  146. extern const fnv1_64_init;
  147. extern const Fnv64_t fnv1a_64_init;
  148. #define FNV1_64_INIT (fnv1_64_init)
  149. #define FNV1A_64_INIT (fnv1a_64_init)
  150. #endif /* HAVE_64BIT_LONG_LONG */
  151. /*
  152. * hash types
  153. */
  154. enum fnv_type {
  155. FNV_NONE = 0, /* invalid FNV hash type */
  156. FNV0_32 = 1, /* FNV-0 32 bit hash */
  157. FNV1_32 = 2, /* FNV-1 32 bit hash */
  158. FNV1a_32 = 3, /* FNV-1a 32 bit hash */
  159. FNV0_64 = 4, /* FNV-0 64 bit hash */
  160. FNV1_64 = 5, /* FNV-1 64 bit hash */
  161. FNV1a_64 = 6, /* FNV-1a 64 bit hash */
  162. };
  163. /*
  164. * these test vectors are used as part o the FNV test suite
  165. */
  166. struct test_vector {
  167. void *buf; /* start of test vector buffer */
  168. int len; /* length of test vector */
  169. };
  170. struct fnv0_32_test_vector {
  171. struct test_vector *test; /* test vector buffer to hash */
  172. Fnv32_t fnv0_32; /* expected FNV-0 32 bit hash value */
  173. };
  174. struct fnv1_32_test_vector {
  175. struct test_vector *test; /* test vector buffer to hash */
  176. Fnv32_t fnv1_32; /* expected FNV-1 32 bit hash value */
  177. };
  178. struct fnv1a_32_test_vector {
  179. struct test_vector *test; /* test vector buffer to hash */
  180. Fnv32_t fnv1a_32; /* expected FNV-1a 32 bit hash value */
  181. };
  182. struct fnv0_64_test_vector {
  183. struct test_vector *test; /* test vector buffer to hash */
  184. Fnv64_t fnv0_64; /* expected FNV-0 64 bit hash value */
  185. };
  186. struct fnv1_64_test_vector {
  187. struct test_vector *test; /* test vector buffer to hash */
  188. Fnv64_t fnv1_64; /* expected FNV-1 64 bit hash value */
  189. };
  190. struct fnv1a_64_test_vector {
  191. struct test_vector *test; /* test vector buffer to hash */
  192. Fnv64_t fnv1a_64; /* expected FNV-1a 64 bit hash value */
  193. };
  194. /*
  195. * external functions
  196. */
  197. /* hash_32.c */
  198. extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval);
  199. extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval);
  200. /* hash_32a.c */
  201. extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval);
  202. extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval);
  203. /* hash_64.c */
  204. extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval);
  205. extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval);
  206. /* hash_64a.c */
  207. extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval);
  208. extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval);
  209. /* test_fnv.c */
  210. extern struct test_vector fnv_test_str[];
  211. extern struct fnv0_32_test_vector fnv0_32_vector[];
  212. extern struct fnv1_32_test_vector fnv1_32_vector[];
  213. extern struct fnv1a_32_test_vector fnv1a_32_vector[];
  214. extern struct fnv0_64_test_vector fnv0_64_vector[];
  215. extern struct fnv1_64_test_vector fnv1_64_vector[];
  216. extern struct fnv1a_64_test_vector fnv1a_64_vector[];
  217. extern void unknown_hash_type(char *prog, enum fnv_type type, int code);
  218. extern void print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg);
  219. extern void print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg);
  220. #endif /* __FNV_H__ */