-- | -- Module : Data.UUID.V5 -- Copyright : (c) 2008 Antoine Latter -- -- License : BSD-style -- -- Maintainer : aslatter@gmail.com -- Stability : experimental -- Portability : portable -- -- -- This module implements Version 5 UUIDs as specified -- in RFC 4122. -- -- These UUIDs identify an object within a namespace, -- and are deterministic. -- -- The namespace is identified by a UUID. Several sample -- namespaces are enclosed. 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 -- |Generate a 'UUID' within the specified namespace out of the given -- object. -- -- Uses a SHA1 hash. generateNamed :: UUID -- ^Namespace -> [Word8] -- ^Object -> 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 -- HASH 0 1 - 2 3 : w1 -- 4 5 - 6 7 : w2 -- 8 9 - 10 11 : w3 -- 12 13 - 14 15 : w4 -- 16 17 - 18 19 : w5 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 -- |The namespace for DNS addresses namespaceDNS :: UUID namespaceDNS = unsafeFromString "6ba7b810-9dad-11d1-80b4-00c04fd430c8" -- |The namespace for URLs 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"