From 855f03627f2bce6a7f725fe6cc92e7ebe8d39deb Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 7 Feb 2017 15:11:37 -0700 Subject: [PATCH] fnv: work with non-64-bit aligned chunks of data Signed-off-by: Jens Axboe --- crc/fnv.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/crc/fnv.c b/crc/fnv.c index 04c0560c..4cd06501 100644 --- a/crc/fnv.c +++ b/crc/fnv.c @@ -2,14 +2,32 @@ #define FNV_PRIME 0x100000001b3ULL +/* + * 64-bit fnv, but don't require 64-bit multiples of data. Use bytes + * for the last unaligned chunk. + */ uint64_t fnv(const void *buf, uint32_t len, uint64_t hval) { const uint64_t *ptr = buf; - const uint64_t *end = (void *) buf + len; - while (ptr < end) { + while (len) { hval *= FNV_PRIME; - hval ^= (uint64_t) *ptr++; + if (len >= sizeof(uint64_t)) { + hval ^= (uint64_t) *ptr++; + len -= sizeof(uint64_t); + continue; + } else { + const uint8_t *ptr8 = (const uint8_t *) ptr; + uint64_t val = 0; + int i; + + for (i = 0; i < len; i++) { + val <<= 8; + val |= (uint8_t) *ptr8++; + } + hval ^= val; + break; + } } return hval; -- 2.25.1