| 1 | #include "fnv.h" |
| 2 | |
| 3 | #define FNV_PRIME 0x100000001b3ULL |
| 4 | |
| 5 | /* |
| 6 | * 64-bit fnv, but don't require 64-bit multiples of data. Use bytes |
| 7 | * for the last unaligned chunk. |
| 8 | */ |
| 9 | uint64_t fnv(const void *buf, uint32_t len, uint64_t hval) |
| 10 | { |
| 11 | const uint64_t *ptr = buf; |
| 12 | |
| 13 | while (len) { |
| 14 | hval *= FNV_PRIME; |
| 15 | if (len >= sizeof(uint64_t)) { |
| 16 | hval ^= (uint64_t) *ptr++; |
| 17 | len -= sizeof(uint64_t); |
| 18 | continue; |
| 19 | } else { |
| 20 | const uint8_t *ptr8 = (const uint8_t *) ptr; |
| 21 | uint64_t val = 0; |
| 22 | int i; |
| 23 | |
| 24 | for (i = 0; i < len; i++) { |
| 25 | val <<= 8; |
| 26 | val |= (uint8_t) *ptr8++; |
| 27 | } |
| 28 | hval ^= val; |
| 29 | break; |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | return hval; |
| 34 | } |