module Distribution.Utils.MD5 (
MD5,
showMD5,
md5,
md5FromInteger,
binaryPutMD5,
binaryGetMD5,
) where
import Data.Binary (Get, Put)
import Data.Binary.Get (getWord64le)
import Data.Binary.Put (putWord64le)
import Data.Bits (complement, shiftR, (.&.))
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
showMD5 :: MD5 -> String
showMD5 :: MD5 -> String
showMD5 (Fingerprint Word64
a Word64
b) = String -> String
pad String
a' forall a. [a] -> [a] -> [a]
++ String -> String
pad String
b' where
a' :: String
a' = forall a. (Integral a, Show a) => a -> String -> String
showHex Word64
a String
""
b' :: String
b' = forall a. (Integral a, Show a) => a -> String -> String
showHex Word64
b String
""
pad :: String -> String
pad String
s = forall a. Int -> a -> [a]
replicate (Int
16 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) Char
'0' forall a. [a] -> [a] -> [a]
++ String
s
md5 :: BS.ByteString -> MD5
md5 :: ByteString -> MD5
md5 ByteString
bs = forall a. IO a -> a
unsafeDupablePerformIO forall a b. (a -> b) -> a -> b
$ forall a. ByteString -> (CStringLen -> IO a) -> IO a
BS.unsafeUseAsCStringLen ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) ->
Ptr Word8 -> Int -> IO MD5
fingerprintData (forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
ptr) Int
len
binaryPutMD5 :: MD5 -> Put
binaryPutMD5 :: MD5 -> Put
binaryPutMD5 (Fingerprint Word64
a Word64
b) = do
Word64 -> Put
putWord64le Word64
a
Word64 -> Put
putWord64le Word64
b
binaryGetMD5 :: Get MD5
binaryGetMD5 :: Get MD5
binaryGetMD5 = do
Word64
a <- Get Word64
getWord64le
Word64
b <- Get Word64
getWord64le
forall (m :: * -> *) a. Monad m => a -> m a
return (Word64 -> Word64 -> MD5
Fingerprint Word64
a Word64
b)
md5FromInteger :: Integer -> MD5
md5FromInteger :: Integer -> MD5
md5FromInteger Integer
i = Word64 -> Word64 -> MD5
Fingerprint Word64
hi Word64
lo where
mask :: Word64
mask = forall a. Bits a => a -> a
complement Word64
0
lo :: Word64
lo = Word64
mask forall a. Bits a => a -> a -> a
.&. forall a. Num a => Integer -> a
fromInteger Integer
i
hi :: Word64
hi = Word64
mask forall a. Bits a => a -> a -> a
.&. forall a. Num a => Integer -> a
fromInteger (Integer
i forall a. Bits a => a -> Int -> a
`shiftR` Int
64)