module Data.UUID.V5
(generateNamed
,namespaceDNS
,namespaceURL
,namespaceOID
,namespaceX500
) where
import Data.UUID.Internal
import Data.Binary
import Data.Bits
import Data.Maybe
import qualified Data.ByteString.Lazy as BS
import Data.ByteString.Lazy (ByteString)
import qualified Data.Digest.SHA1 as SHA1
generateNamed :: UUID
-> [Word8]
-> UUID
generateNamed namespace object =
let chunk = BS.unpack (encode namespace) ++ object
SHA1.Word160 w1 w2 w3 w4 w5 = SHA1.hash chunk
tl = w1
tm = high16 w2
th = (versionSHA .|.) $ (versionMask .&.) $ low16 w2
ch = (reserved .|.) $ (reservedMask .&.) $ high8 $ high16 w3
cl = low8 $ high16 w3
node = Node (high8 (low16 w3))
(low8 (low16 w3))
(high8 (high16 w4))
(low8 (high16 w4))
(high8 (low16 w4))
(low8 (low16 w4))
in UUID tl tm th ch cl node
low16 :: Word32 -> Word16
low16 = fromIntegral . (.&. 0x0000FFFF)
high16 :: Word32 -> Word16
high16 = fromIntegral . flip shiftR 16
low8 :: Word16 -> Word8
low8 = fromIntegral . (.&. 0x00FF)
high8 :: Word16 -> Word8
high8 = fromIntegral . flip shiftR 8
versionSHA = 5 `shiftL` 12
unsafeFromString :: String -> UUID
unsafeFromString = fromJust . fromString
namespaceDNS :: UUID
namespaceDNS = unsafeFromString "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
namespaceURL :: UUID
namespaceURL = unsafeFromString "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
namespaceOID :: UUID
namespaceOID = unsafeFromString "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
namespaceX500 :: UUID
namespaceX500 = unsafeFromString "6ba7b814-9dad-11d1-80b4-00c04fd430c8"