-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Principled, portable & extensible hashing of data and types, including an implementation of the FNV-1a and SipHash algorithms. -- -- This package is a rewrite of the hashable library by Milan -- Straka and Johan Tibell, having the following goals: -- -- -- -- Versioning: Except for instances where we specifically note -- that we make no promise of consistency, changes to hash values (and -- consequently changes to StableHashable values, where -- applicable) entail a major version number bump. @package hashabler @version 1.2 module Data.Hashabler newtype Hash32 a Hash32 :: Word32 -> Hash32 a [hashWord32] :: Hash32 a -> Word32 newtype Hash64 a Hash64 :: Word64 -> Hash64 a [hashWord64] :: Hash64 a -> Word64 data Hash128 a Hash128 :: !Word64 -> !Word64 -> Hash128 a [hashWord128_0] :: Hash128 a -> !Word64 [hashWord128_1] :: Hash128 a -> !Word64 -- | A 128-bit secret key. This should be generated randomly and must be -- kept secret. data SipKey SipKey :: !Word64 -> !Word64 -> SipKey -- | An implementation of 64-bit siphash-2-4. -- -- This function is fast on 64-bit machines, and provides very good -- hashing properties and protection against hash flooding attacks. siphash64 :: Hashable a => SipKey -> a -> Hash64 a -- | An implementation of 128-bit siphash-2-4. -- -- This function is fast on 64-bit machines, and provides very good -- hashing properties and protection against hash flooding attacks. siphash128 :: Hashable a => SipKey -> a -> Hash128 a -- | Hash a value using the standard spec-prescribed 32-bit seed value. -- --
--   hashFNV32 = Hash32 . fnv32 . hash fnvOffsetBasis32
--   
hashFNV32 :: Hashable a => a -> Hash32 a -- | Hash a value using the standard spec-prescribed 64-bit seed value. -- This may be slow on 32-bit machines. -- --
--   hashFNV64 = Hash64 . fnv64 . hash fnvOffsetBasis64
--   
hashFNV64 :: Hashable a => a -> Hash64 a fnvPrime32 :: Word32 fnvPrime64 :: Word64 fnvOffsetBasis32 :: FNV32 fnvOffsetBasis64 :: FNV64 -- | A class of types that can be converted into a hash value. We expect -- all instances to display "good" hashing properties (wrt -- avalanche, bit independence, etc.) when passed to an ideal hash -- function. -- -- We try to ensure that bytes are extracted from values in a way that is -- portable across architectures (where possible), and straightforward to -- replicate on other platforms and in other languages. Portable -- instances are also instances of StableHashable, and -- non-portable instances are NOTE-ed in instance docs here as -- well. -- -- See the section "Defining Hashable instances" for details of -- what we expect from instances. class Hashable a -- | Add the bytes from the second argument into the hash, producing a new -- hash value. This is essentially a left fold of the methods of -- HashState over individual bytes extracted from a. -- -- For some instances of HashState, this method might be a -- complete hashing algorithm, or might comprise the core of a hashing -- algorithm (perhaps with some final mixing), or might do something -- completely apart from hashing (e.g. simply cons bytes into a list for -- debugging). -- -- Implementations must ensure that, for the same data: -- -- -- -- ...are consistent across architectures of different word size and -- endianness. For example do not define an instance which conditionally -- implements mix64 only on 64-bit architectures. hash :: (Hashable a, HashState h) => h -> a -> h -- |
--   mixConstructor n h = h `mix8` (0xFF - n)
--   
mixConstructor :: (HashState h) => Word8 -> h -> h -- | Types whose hashes can be compared across platforms. This is somewhat -- like a limited, but cross-platform Typeable. -- -- Instances are expected to be universally-unique, and should be -- generated randomly. Type parameters can be hashed together using -- mixType, like: -- --
--   instance (StableHashable b) => StableHashable (A b) where
--       typeHash = mixType (TypeHash 530184177609460980)
--   
-- -- When Hashable instances change, the TypeHash must be -- changed to a new random value. This lets us "version" a set of hashes; -- if we store a TypeHash along with a set of hashes in program -- A, in program B we can compare the stored value with our -- own TypeHash and verify that hashes we generate in program -- B can be meaningfully compared. -- -- Note, obviously this doesn't ensure that values were hashed with the -- same hashing algorithm, and you should come up with your own means to -- serialize that information if you need to. class Hashable a => StableHashable a typeHash :: StableHashable a => TypeHash a -- | A value that uniquely identifies a StableHashable type. This -- serves to both version a type with respect to its Hashable -- instance, and distinguish types from each other (similar to -- TypeRep) across program runs, platforms and library versions. newtype TypeHash (a :: k) TypeHash :: Word64 -> TypeHash [typeHashWord] :: TypeHash -> Word64 -- | A helper for implementing typeHash by xor-ing type -- parameters with a new random hash value. E.g.: -- --
--   instance (StableHashable a, StableHashable b) => StableHashable (a, b) where
--       typeHash = mixType (mixType (TypeHash 12071780118071628513))
--                                             __ a new random value for (,)
--                              ____ mix in the type hash for a
--                      __ mix in the type hash for b
--   
mixType :: StableHashable a => TypeHash t -> TypeHash (t a) typeHashOf :: StableHashable a => a -> TypeHash a typeHashOfProxy :: StableHashable a => proxy a -> TypeHash a -- | A class for defining how a hash function consumes input data. Bytes -- are fed to these methods in our Hashable instances, which -- promise to call these methods in a platform-independent way. -- -- Instances of HashState only need to define mix8, but may -- additionally handle mix-ing in larger word chunks for -- performance reasons. For instance a hash function which operates on -- four bytes at a time might make use of mix32, and perhaps in -- mix8 pad with three additional 0s. -- -- Endianness is normalized in Hashable instances, so these mix -- methods can expect to receive identical words across platforms. class HashState h where mix16 h = \ wd16 -> let (wd8_0, wd8_1) = bytes16 wd16 in h `mix8` wd8_0 `mix8` wd8_1 mix32 h = \ wd32 -> let (b0, b1, b2, b3) = bytes32 wd32 in h `mix8` b0 `mix8` b1 `mix8` b2 `mix8` b3 mix64 h = \ wd64 -> let (w32_0, w32_1) = words32 wd64 in h `mix32` w32_0 `mix32` w32_1 -- | Mix in one byte. mix8 :: HashState h => h -> Word8 -> h -- | Mix in a 2-byte word. Defaults to two mix8 on bytes from most -- to least significant. mix16 :: HashState h => h -> Word16 -> h -- | Mix in a 4-byte word. Defaults to four mix8 on bytes from most -- to least significant. mix32 :: HashState h => h -> Word32 -> h -- | Mix in a 8-byte word. Defaults to two mix32 on 32-byte words -- from most to least significant. mix64 :: HashState h => h -> Word64 -> h