module Distribution.Utils.MD5 ( MD5, showMD5, md5, -- * Binary binaryPutMD5, binaryGetMD5, ) where import Data.Binary (Get, Put) import Data.Binary.Get (getWord64le) import Data.Binary.Put (putWord64le) import Foreign.Ptr (castPtr) import GHC.Fingerprint (Fingerprint (..), fingerprintData) import Numeric (showHex) import System.IO.Unsafe (unsafeDupablePerformIO) import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BS type MD5 = Fingerprint -- | Show 'MD5' in human readable form -- -- >>> showMD5 (Fingerprint 123 456) -- "000000000000007b00000000000001c8" -- -- >>> showMD5 $ md5 $ BS.pack [0..127] -- "37eff01866ba3f538421b30b7cbefcac" -- -- @since 3.2.0.0 showMD5 :: MD5 -> String showMD5 (Fingerprint a b) = pad a' ++ pad b' where a' = showHex a "" b' = showHex b "" pad s = replicate (16 - length s) '0' ++ s -- | @since 3.2.0.0 md5 :: BS.ByteString -> MD5 md5 bs = unsafeDupablePerformIO $ BS.unsafeUseAsCStringLen bs $ \(ptr, len) -> fingerprintData (castPtr ptr) len -- | @since 3.2.0.0 binaryPutMD5 :: MD5 -> Put binaryPutMD5 (Fingerprint a b) = do putWord64le a putWord64le b -- | @since 3.2.0.0 binaryGetMD5 :: Get MD5 binaryGetMD5 = do a <- getWord64le b <- getWord64le return (Fingerprint a b)