{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- -- Module : Data.Digest.Pure.HashMD5 -- License : BSD3 -- Stability : experimental -- Portability : portable, requires bang patterns and ByteString -- Tested with : GHC-6.12.2 -- -- Use the MD5-rounds to compute hash-values for data-structures. ----------------------------------------------------------------------------- module Data.Digest.Pure.HashMD5 ( MD5Digest , Hash(..) , md5Init , mixRaw , mix , mix3 , mix4 , mix5 , mixInt , foldHash ) where import Data.Digest.Pure.MD5 import Data.Char {-# INLINE mix5 #-} mix5 :: MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest mix5 a (MD5Digest w0 w1 w2 w3) (MD5Digest w4 w5 w6 w7) (MD5Digest w8 w9 w10 w11) (MD5Digest w12 w13 w14 w15) = mixRaw a w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 {-# INLINE mix4 #-} mix4 :: MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest mix4 a b c d = mix5 md5Init a b c d {-# INLINE mix3 #-} mix3 :: MD5Digest -> MD5Digest -> MD5Digest -> MD5Digest mix3 a b c = mix5 md5Init md5Init a b c {-# INLINE mix #-} mix :: MD5Digest -> MD5Digest -> MD5Digest mix a b = mix5 md5Init md5Init md5Init a b class Hash a where hash :: a -> MD5Digest -- instance Monoid HashMD5 instance Hash MD5Digest where hash = id instance Hash Char where hash c = mixRaw md5Init (fromIntegral $ ord c) 234124 23415 3452 0 0 0 0 0 0 0 0 0 0 0 0 instance (Hash a, Hash b) => Hash (a,b) where hash (a, b) = mix (hash a) (hash b) instance (Hash a, Hash b, Hash c) => Hash (a, b, c) where hash (a, b, c) = mix3 (hash a) (hash b) (hash c) instance (Hash a, Hash b, Hash c, Hash d) => Hash (a, b, c, d) where hash (a, b, c, d) = mix4 (hash a) (hash b) (hash c) (hash d) hashString :: String -> MD5Digest hashString = foldHash $ mixRaw md5Init 234 42 21 23 0 0 0 0 0 0 0 0 0 0 0 0 instance Hash a => Hash [a] where hash = foldHash (hashString "Prelude.List standart") foldHash :: Hash a => MD5Digest -> [a] -> MD5Digest foldHash !acc [] = acc foldHash !acc [a] = mix acc (hash a) foldHash !acc [a,b] = mix3 acc (hash a) (hash b) foldHash !acc [a,b,c] = mix4 acc (hash a) (hash b) (hash c) foldHash !acc (a:b:c:d:rest) = foldHash (mix5 acc (hash a) (hash b) (hash c) (hash d)) rest {-# inline mixInt #-} mixInt :: MD5Digest -> Int -> MD5Digest mixInt h i = mixRaw h (fromIntegral i) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 {- foldInt :: Hash64 -> [Int] -> Hash64 foldInt !acc [] = acc foldInt !acc [a] = mixRaw acc (fromIntegral a) 0 0 0 foldInt !acc [a,b] = mixRaw acc (fromIntegral a) (fromIntegral b) 0 0 foldInt !acc [a,b,c] = mixRaw acc (fromIntegral a) (fromIntegral b) (fromIntegral c) 0 foldInt !acc [a,b,c,d] = mixRaw acc (fromIntegral a) (fromIntegral b) (fromIntegral c) (fromIntegral d) foldInt !acc (a:b:c:d:rest) = foldInt (mixRaw acc (fromIntegral a) (fromIntegral b) (fromIntegral c) (fromIntegral d)) rest -}