Skip to content

Instantly share code, notes, and snippets.

@drchaos
Last active May 3, 2023 15:37
Show Gist options
  • Save drchaos/6fa9117cc13c297e1dd9015fccdf2908 to your computer and use it in GitHub Desktop.
Save drchaos/6fa9117cc13c297e1dd9015fccdf2908 to your computer and use it in GitHub Desktop.
--------------------- Idiomatic ------------------------
fnvPrime32 :: Word32
fnvPrime32 = 16777619
fnvOffsetBasis32 :: Word32
fnvOffsetBasis32 = 2166136261
fnv1aHash32Word32 :: Word32 -> Word32 -> Word32
fnv1aHash32Word32 base word =
let b0 = fromIntegral $ word .&. 0xFF
b1 = fromIntegral $ (word `shiftR` 8) .&. 0xFF
b2 = fromIntegral $ (word `shiftR` 16) .&. 0xFF
b3 = fromIntegral $ (word `shiftR` 24) .&. 0xFF
in foldl fnv1aHash32Base base [b0, b1, b2, b3]
fnv1aHash32Base :: Word32 -> Word8 -> Word32
fnv1aHash32Base base byte = (base `xor` (fromIntegral byte)) * fnvPrime32
hashPlus :: Word32 -> Word32 -> Word32
hashPlus l r = fnvOffsetBasis32 <<>> l <<>> r
where (<<>>) = fnv1aHash32Word32
--------------------- C-like ------------------------
fnv1a_32 :: Ptr Word8 -> Int -> IO Word32
fnv1a_32 !ptr !n = fnv1a_32_ ptr n fnvOffsetBasis32
fnv1a_32_ :: Ptr Word8 -> Int -> Word32 -> IO Word32
fnv1a_32_ !ptr !n a = loop a 0
where
loop !acc !i
| i == n = return $! acc
| otherwise = do
!x <- peekByteOff @Word8 ptr i
loop (fnvPrime32 * (acc `xor` fromIntegral x)) (i + 1)
hashPlusС :: Word32 -> Word32 -> Word32
hashPlusС l r = B.unsafeDupablePerformIO $!
withArray lst $ \ptr ->
fnv1a_32 (castPtr ptr) size
where lst = [l,r]
size = 2 * sizeOf(undefined::Word32)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment