fork(2) download
  1. #include<stdint.h>
  2. #define HAVE_64BIT_LONG_LONG
  3. typedef uint64_t u_int64_t;
  4. typedef uint32_t u_int32_t;
  5.  
  6. /*
  7.  * fnv - Fowler/Noll/Vo- hash code
  8.  *
  9.  * @(#) $Revision: 5.4 $
  10.  * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $
  11.  * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $
  12.  *
  13.  ***
  14.  *
  15.  * Fowler/Noll/Vo- hash
  16.  *
  17.  * The basis of this hash algorithm was taken from an idea sent
  18.  * as reviewer comments to the IEEE POSIX P1003.2 committee by:
  19.  *
  20.  * Phong Vo (http://w...content-available-to-author-only...t.com/info/kpv/)
  21.  * Glenn Fowler (http://w...content-available-to-author-only...t.com/~gsf/)
  22.  *
  23.  * In a subsequent ballot round:
  24.  *
  25.  * Landon Curt Noll (http://w...content-available-to-author-only...e.com/chongo/)
  26.  *
  27.  * improved on their algorithm. Some people tried this hash
  28.  * and found that it worked rather well. In an EMail message
  29.  * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
  30.  *
  31.  * FNV hashes are designed to be fast while maintaining a low
  32.  * collision rate. The FNV speed allows one to quickly hash lots
  33.  * of data while maintaining a reasonable collision rate. See:
  34.  *
  35.  * http://w...content-available-to-author-only...e.com/chongo/tech/comp/fnv/index.html
  36.  *
  37.  * for more details as well as other forms of the FNV hash.
  38.  *
  39.  ***
  40.  *
  41.  * NOTE: The FNV-0 historic hash is not recommended. One should use
  42.  * the FNV-1 hash instead.
  43.  *
  44.  * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the
  45.  * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
  46.  *
  47.  * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
  48.  * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  49.  *
  50.  * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
  51.  * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str().
  52.  *
  53.  * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
  54.  * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  55.  *
  56.  * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
  57.  * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
  58.  *
  59.  * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the
  60.  * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str().
  61.  *
  62.  ***
  63.  *
  64.  * Please do not copyright this code. This code is in the public domain.
  65.  *
  66.  * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  67.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  68.  * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  69.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  70.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  71.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  72.  * PERFORMANCE OF THIS SOFTWARE.
  73.  *
  74.  * By:
  75.  * chongo <Landon Curt Noll> /\oo/\
  76.  * http://w...content-available-to-author-only...e.com/chongo/
  77.  *
  78.  * Share and Enjoy! :-)
  79.  */
  80.  
  81. #if !defined(__FNV_H__)
  82. #define __FNV_H__
  83.  
  84. #include <sys/types.h>
  85.  
  86. #define FNV_VERSION "5.0.2" /* @(#) FNV Version */
  87.  
  88.  
  89. /*
  90.  * 32 bit FNV-0 hash type
  91.  */
  92. typedef u_int32_t Fnv32_t;
  93.  
  94.  
  95. /*
  96.  * 32 bit FNV-0 zero initial basis
  97.  *
  98.  * This historic hash is not recommended. One should use
  99.  * the FNV-1 hash and initial basis instead.
  100.  */
  101. #define FNV0_32_INIT ((Fnv32_t)0)
  102.  
  103.  
  104. /*
  105.  * 32 bit FNV-1 and FNV-1a non-zero initial basis
  106.  *
  107.  * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
  108.  *
  109.  * chongo <Landon Curt Noll> /\../\
  110.  *
  111.  * NOTE: The \'s above are not back-slashing escape characters.
  112.  * They are literal ASCII backslash 0x5c characters.
  113.  *
  114.  * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
  115.  */
  116. #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5)
  117. #define FNV1_32A_INIT FNV1_32_INIT
  118.  
  119.  
  120. /*
  121.  * determine how 64 bit unsigned values are represented
  122.  */
  123.  
  124. /*
  125.  * 64 bit FNV-0 hash
  126.  */
  127. #if defined(HAVE_64BIT_LONG_LONG)
  128. typedef u_int64_t Fnv64_t;
  129. #else /* HAVE_64BIT_LONG_LONG */
  130. typedef struct {
  131. u_int32_t w32[2]; /* w32[0] is low order, w32[1] is high order word */
  132. } Fnv64_t;
  133. #endif /* HAVE_64BIT_LONG_LONG */
  134.  
  135.  
  136. /*
  137.  * 64 bit FNV-0 zero initial basis
  138.  *
  139.  * This historic hash is not recommended. One should use
  140.  * the FNV-1 hash and initial basis instead.
  141.  */
  142. #if defined(HAVE_64BIT_LONG_LONG)
  143. #define FNV0_64_INIT ((Fnv64_t)0)
  144. #else /* HAVE_64BIT_LONG_LONG */
  145. extern const Fnv64_t fnv0_64_init;
  146. #define FNV0_64_INIT (fnv0_64_init)
  147. #endif /* HAVE_64BIT_LONG_LONG */
  148.  
  149.  
  150. /*
  151.  * 64 bit FNV-1 non-zero initial basis
  152.  *
  153.  * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
  154.  *
  155.  * chongo <Landon Curt Noll> /\../\
  156.  *
  157.  * NOTE: The \'s above are not back-slashing escape characters.
  158.  * They are literal ASCII backslash 0x5c characters.
  159.  *
  160.  * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
  161.  */
  162. #if defined(HAVE_64BIT_LONG_LONG)
  163. #define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL)
  164. #define FNV1A_64_INIT FNV1_64_INIT
  165. #else /* HAVE_64BIT_LONG_LONG */
  166. extern const fnv1_64_init;
  167. extern const Fnv64_t fnv1a_64_init;
  168. #define FNV1_64_INIT (fnv1_64_init)
  169. #define FNV1A_64_INIT (fnv1a_64_init)
  170. #endif /* HAVE_64BIT_LONG_LONG */
  171.  
  172.  
  173. /*
  174.  * hash types
  175.  */
  176. enum fnv_type {
  177. FNV_NONE = 0, /* invalid FNV hash type */
  178. FNV0_32 = 1, /* FNV-0 32 bit hash */
  179. FNV1_32 = 2, /* FNV-1 32 bit hash */
  180. FNV1a_32 = 3, /* FNV-1a 32 bit hash */
  181. FNV0_64 = 4, /* FNV-0 64 bit hash */
  182. FNV1_64 = 5, /* FNV-1 64 bit hash */
  183. FNV1a_64 = 6, /* FNV-1a 64 bit hash */
  184. };
  185.  
  186.  
  187. /*
  188.  * these test vectors are used as part o the FNV test suite
  189.  */
  190. struct test_vector {
  191. void *buf; /* start of test vector buffer */
  192. int len; /* length of test vector */
  193. };
  194. struct fnv0_32_test_vector {
  195. struct test_vector *test; /* test vector buffer to hash */
  196. Fnv32_t fnv0_32; /* expected FNV-0 32 bit hash value */
  197. };
  198. struct fnv1_32_test_vector {
  199. struct test_vector *test; /* test vector buffer to hash */
  200. Fnv32_t fnv1_32; /* expected FNV-1 32 bit hash value */
  201. };
  202. struct fnv1a_32_test_vector {
  203. struct test_vector *test; /* test vector buffer to hash */
  204. Fnv32_t fnv1a_32; /* expected FNV-1a 32 bit hash value */
  205. };
  206. struct fnv0_64_test_vector {
  207. struct test_vector *test; /* test vector buffer to hash */
  208. Fnv64_t fnv0_64; /* expected FNV-0 64 bit hash value */
  209. };
  210. struct fnv1_64_test_vector {
  211. struct test_vector *test; /* test vector buffer to hash */
  212. Fnv64_t fnv1_64; /* expected FNV-1 64 bit hash value */
  213. };
  214. struct fnv1a_64_test_vector {
  215. struct test_vector *test; /* test vector buffer to hash */
  216. Fnv64_t fnv1a_64; /* expected FNV-1a 64 bit hash value */
  217. };
  218.  
  219.  
  220. /*
  221.  * external functions
  222.  */
  223. /* hash_32.c */
  224. extern Fnv32_t fnv_32_buf(void *buf, size_t len, Fnv32_t hashval);
  225. extern Fnv32_t fnv_32_str(char *buf, Fnv32_t hashval);
  226.  
  227. /* hash_32a.c */
  228. extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval);
  229. extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval);
  230.  
  231. /* hash_64.c */
  232. extern Fnv64_t fnv_64_buf(void *buf, size_t len, Fnv64_t hashval);
  233. extern Fnv64_t fnv_64_str(char *buf, Fnv64_t hashval);
  234.  
  235. /* hash_64a.c */
  236. extern Fnv64_t fnv_64a_buf(void *buf, size_t len, Fnv64_t hashval);
  237. extern Fnv64_t fnv_64a_str(char *buf, Fnv64_t hashval);
  238.  
  239. /* test_fnv.c */
  240. extern struct test_vector fnv_test_str[];
  241. extern struct fnv0_32_test_vector fnv0_32_vector[];
  242. extern struct fnv1_32_test_vector fnv1_32_vector[];
  243. extern struct fnv1a_32_test_vector fnv1a_32_vector[];
  244. extern struct fnv0_64_test_vector fnv0_64_vector[];
  245. extern struct fnv1_64_test_vector fnv1_64_vector[];
  246. extern struct fnv1a_64_test_vector fnv1a_64_vector[];
  247. extern void unknown_hash_type(char *prog, enum fnv_type type, int code);
  248. extern void print_fnv32(Fnv32_t hval, Fnv32_t mask, int verbose, char *arg);
  249. extern void print_fnv64(Fnv64_t hval, Fnv64_t mask, int verbose, char *arg);
  250.  
  251.  
  252. #endif /* __FNV_H__ */
  253.  
  254. /*
  255.  * hash_64 - 64 bit Fowler/Noll/Vo-0 hash code
  256.  *
  257.  * @(#) $Revision: 5.1 $
  258.  * @(#) $Id: hash_64.c,v 5.1 2009/06/30 09:01:38 chongo Exp $
  259.  * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_64.c,v $
  260.  *
  261.  ***
  262.  *
  263.  * Fowler/Noll/Vo hash
  264.  *
  265.  * The basis of this hash algorithm was taken from an idea sent
  266.  * as reviewer comments to the IEEE POSIX P1003.2 committee by:
  267.  *
  268.  * Phong Vo (http://w...content-available-to-author-only...t.com/info/kpv/)
  269.  * Glenn Fowler (http://w...content-available-to-author-only...t.com/~gsf/)
  270.  *
  271.  * In a subsequent ballot round:
  272.  *
  273.  * Landon Curt Noll (http://w...content-available-to-author-only...e.com/chongo/)
  274.  *
  275.  * improved on their algorithm. Some people tried this hash
  276.  * and found that it worked rather well. In an EMail message
  277.  * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
  278.  *
  279.  * FNV hashes are designed to be fast while maintaining a low
  280.  * collision rate. The FNV speed allows one to quickly hash lots
  281.  * of data while maintaining a reasonable collision rate. See:
  282.  *
  283.  * http://w...content-available-to-author-only...e.com/chongo/tech/comp/fnv/index.html
  284.  *
  285.  * for more details as well as other forms of the FNV hash.
  286.  *
  287.  ***
  288.  *
  289.  * NOTE: The FNV-0 historic hash is not recommended. One should use
  290.  * the FNV-1 hash instead.
  291.  *
  292.  * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the
  293.  * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  294.  *
  295.  * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the
  296.  * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str().
  297.  *
  298.  ***
  299.  *
  300.  * Please do not copyright this code. This code is in the public domain.
  301.  *
  302.  * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  303.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
  304.  * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  305.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  306.  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  307.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  308.  * PERFORMANCE OF THIS SOFTWARE.
  309.  *
  310.  * By:
  311.  * chongo <Landon Curt Noll> /\oo/\
  312.  * http://w...content-available-to-author-only...e.com/chongo/
  313.  *
  314.  * Share and Enjoy! :-)
  315.  */
  316.  
  317. #include <stdlib.h>
  318.  
  319.  
  320. /*
  321.  * FNV-0 defines the initial basis to be zero
  322.  */
  323. #if !defined(HAVE_64BIT_LONG_LONG)
  324. const Fnv64_t fnv0_64_init = { 0UL, 0UL };
  325. #endif /* ! HAVE_64BIT_LONG_LONG */
  326.  
  327.  
  328. /*
  329.  * FNV-1 defines the initial basis to be non-zero
  330.  */
  331. #if !defined(HAVE_64BIT_LONG_LONG)
  332. const Fnv64_t fnv1_64_init = { 0x84222325UL, 0xcbf29ce4UL };
  333. #endif /* ! HAVE_64BIT_LONG_LONG */
  334.  
  335.  
  336. /*
  337.  * 64 bit magic FNV-0 and FNV-1 prime
  338.  */
  339. #if defined(HAVE_64BIT_LONG_LONG)
  340. #define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL)
  341. #else /* HAVE_64BIT_LONG_LONG */
  342. #define FNV_64_PRIME_LOW ((unsigned long)0x1b3) /* lower bits of FNV prime */
  343. #define FNV_64_PRIME_SHIFT (8) /* top FNV prime shift above 2^32 */
  344. #endif /* HAVE_64BIT_LONG_LONG */
  345.  
  346.  
  347. /*
  348.  * fnv_64_buf - perform a 64 bit Fowler/Noll/Vo hash on a buffer
  349.  *
  350.  * input:
  351.  * buf - start of buffer to hash
  352.  * len - length of buffer in octets
  353.  * hval - previous hash value or 0 if first call
  354.  *
  355.  * returns:
  356.  * 64 bit hash as a static hash type
  357.  *
  358.  * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval
  359.  * argument on the first call to either fnv_64_buf() or fnv_64_str().
  360.  *
  361.  * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval
  362.  * argument on the first call to either fnv_64_buf() or fnv_64_str().
  363.  */
  364. Fnv64_t
  365. fnv_64_buf(void *buf, size_t len, Fnv64_t hval)
  366. {
  367. unsigned char *bp = (unsigned char *)buf; /* start of buffer */
  368. unsigned char *be = bp + len; /* beyond end of buffer */
  369.  
  370. #if defined(HAVE_64BIT_LONG_LONG)
  371.  
  372. /*
  373.   * FNV-1 hash each octet of the buffer
  374.   */
  375. while (bp < be) {
  376.  
  377. /* multiply by the 64 bit FNV magic prime mod 2^64 */
  378. #if defined(NO_FNV_GCC_OPTIMIZATION)
  379. hval *= FNV_64_PRIME;
  380. #else /* NO_FNV_GCC_OPTIMIZATION */
  381. hval += (hval << 1) + (hval << 4) + (hval << 5) +
  382. (hval << 7) + (hval << 8) + (hval << 40);
  383. #endif /* NO_FNV_GCC_OPTIMIZATION */
  384.  
  385. /* xor the bottom with the current octet */
  386. hval ^= (Fnv64_t)*bp++;
  387. }
  388.  
  389. #else /* HAVE_64BIT_LONG_LONG */
  390.  
  391. unsigned long val[4]; /* hash value in base 2^16 */
  392. unsigned long tmp[4]; /* tmp 64 bit value */
  393.  
  394. /*
  395.   * Convert Fnv64_t hval into a base 2^16 array
  396.   */
  397. val[0] = hval.w32[0];
  398. val[1] = (val[0] >> 16);
  399. val[0] &= 0xffff;
  400. val[2] = hval.w32[1];
  401. val[3] = (val[2] >> 16);
  402. val[2] &= 0xffff;
  403.  
  404. /*
  405.   * FNV-1 hash each octet of the buffer
  406.   */
  407. while (bp < be) {
  408.  
  409. /*
  410. * multiply by the 64 bit FNV magic prime mod 2^64
  411. *
  412. * Using 0x100000001b3 we have the following digits base 2^16:
  413. *
  414. * 0x0 0x100 0x0 0x1b3
  415. *
  416. * which is the same as:
  417. *
  418. * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
  419. */
  420. /* multiply by the lowest order digit base 2^16 */
  421. tmp[0] = val[0] * FNV_64_PRIME_LOW;
  422. tmp[1] = val[1] * FNV_64_PRIME_LOW;
  423. tmp[2] = val[2] * FNV_64_PRIME_LOW;
  424. tmp[3] = val[3] * FNV_64_PRIME_LOW;
  425. /* multiply by the other non-zero digit */
  426. tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
  427. tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
  428. /* propagate carries */
  429. tmp[1] += (tmp[0] >> 16);
  430. val[0] = tmp[0] & 0xffff;
  431. tmp[2] += (tmp[1] >> 16);
  432. val[1] = tmp[1] & 0xffff;
  433. val[3] = tmp[3] + (tmp[2] >> 16);
  434. val[2] = tmp[2] & 0xffff;
  435. /*
  436. * Doing a val[3] &= 0xffff; is not really needed since it simply
  437. * removes multiples of 2^64. We can discard these excess bits
  438. * outside of the loop when we convert to Fnv64_t.
  439. */
  440.  
  441. /* xor the bottom with the current octet */
  442. val[0] ^= (unsigned long)*bp++;
  443. }
  444.  
  445. /*
  446.   * Convert base 2^16 array back into an Fnv64_t
  447.   */
  448. hval.w32[1] = ((val[3]<<16) | val[2]);
  449. hval.w32[0] = ((val[1]<<16) | val[0]);
  450.  
  451. #endif /* HAVE_64BIT_LONG_LONG */
  452.  
  453. /* return our new hash value */
  454. return hval;
  455. }
  456.  
  457.  
  458. /*
  459.  * fnv_64_str - perform a 64 bit Fowler/Noll/Vo hash on a buffer
  460.  *
  461.  * input:
  462.  * buf - start of buffer to hash
  463.  * hval - previous hash value or 0 if first call
  464.  *
  465.  * returns:
  466.  * 64 bit hash as a static hash type
  467.  *
  468.  * NOTE: To use the 64 bit FNV-0 historic hash, use FNV0_64_INIT as the hval
  469.  * argument on the first call to either fnv_64_buf() or fnv_64_str().
  470.  *
  471.  * NOTE: To use the recommended 64 bit FNV-1 hash, use FNV1_64_INIT as the hval
  472.  * argument on the first call to either fnv_64_buf() or fnv_64_str().
  473.  */
  474. Fnv64_t
  475. fnv_64_str(char *str, Fnv64_t hval)
  476. {
  477. unsigned char *s = (unsigned char *)str; /* unsigned string */
  478.  
  479. #if defined(HAVE_64BIT_LONG_LONG)
  480.  
  481. /*
  482.   * FNV-1 hash each octet of the string
  483.   */
  484. while (*s) {
  485.  
  486. /* multiply by the 64 bit FNV magic prime mod 2^64 */
  487. #if defined(NO_FNV_GCC_OPTIMIZATION)
  488. hval *= FNV_64_PRIME;
  489. #else /* NO_FNV_GCC_OPTIMIZATION */
  490. hval += (hval << 1) + (hval << 4) + (hval << 5) +
  491. (hval << 7) + (hval << 8) + (hval << 40);
  492. #endif /* NO_FNV_GCC_OPTIMIZATION */
  493.  
  494. /* xor the bottom with the current octet */
  495. hval ^= (Fnv64_t)*s++;
  496. }
  497.  
  498. #else /* !HAVE_64BIT_LONG_LONG */
  499.  
  500. unsigned long val[4]; /* hash value in base 2^16 */
  501. unsigned long tmp[4]; /* tmp 64 bit value */
  502.  
  503. /*
  504.   * Convert Fnv64_t hval into a base 2^16 array
  505.   */
  506. val[0] = hval.w32[0];
  507. val[1] = (val[0] >> 16);
  508. val[0] &= 0xffff;
  509. val[2] = hval.w32[1];
  510. val[3] = (val[2] >> 16);
  511. val[2] &= 0xffff;
  512.  
  513. /*
  514.   * FNV-1 hash each octet of the string
  515.   */
  516. while (*s) {
  517.  
  518. /*
  519. * multiply by the 64 bit FNV magic prime mod 2^64
  520. *
  521. * Using 1099511628211, we have the following digits base 2^16:
  522. *
  523. * 0x0 0x100 0x0 0x1b3
  524. *
  525. * which is the same as:
  526. *
  527. * 0x0 1<<FNV_64_PRIME_SHIFT 0x0 FNV_64_PRIME_LOW
  528. */
  529. /* multiply by the lowest order digit base 2^16 */
  530. tmp[0] = val[0] * FNV_64_PRIME_LOW;
  531. tmp[1] = val[1] * FNV_64_PRIME_LOW;
  532. tmp[2] = val[2] * FNV_64_PRIME_LOW;
  533. tmp[3] = val[3] * FNV_64_PRIME_LOW;
  534. /* multiply by the other non-zero digit */
  535. tmp[2] += val[0] << FNV_64_PRIME_SHIFT; /* tmp[2] += val[0] * 0x100 */
  536. tmp[3] += val[1] << FNV_64_PRIME_SHIFT; /* tmp[3] += val[1] * 0x100 */
  537. /* propagate carries */
  538. tmp[1] += (tmp[0] >> 16);
  539. val[0] = tmp[0] & 0xffff;
  540. tmp[2] += (tmp[1] >> 16);
  541. val[1] = tmp[1] & 0xffff;
  542. val[3] = tmp[3] + (tmp[2] >> 16);
  543. val[2] = tmp[2] & 0xffff;
  544. /*
  545. * Doing a val[3] &= 0xffff; is not really needed since it simply
  546. * removes multiples of 2^64. We can discard these excess bits
  547. * outside of the loop when we convert to Fnv64_t.
  548. */
  549.  
  550. /* xor the bottom with the current octet */
  551. val[0] ^= (unsigned long)(*s++);
  552. }
  553.  
  554. /*
  555.   * Convert base 2^16 array back into an Fnv64_t
  556.   */
  557. hval.w32[1] = ((val[3]<<16) | val[2]);
  558. hval.w32[0] = ((val[1]<<16) | val[0]);
  559.  
  560. #endif /* !HAVE_64BIT_LONG_LONG */
  561.  
  562. /* return our new hash value */
  563. return hval;
  564. }
  565.  
  566. #include<stdio.h>
  567. int main()
  568. {
  569. printf("%llx\n", fnv_64_str("Hello", FNV1_64_INIT));
  570. }
  571.  
Success #stdin #stdout 0s 2156KB
stdin
Standard input is empty
stdout
fa365282a44c0ba7