Skip to content

Commit 2c83c63

Browse files
committed
Export a md5DigestBytes function to get access to the raw bytes
The existing Show instance provides a convenient way to get the hex representation and the Binary and Serialise instances also provide access to the raw bytes. That said, the documentation does not make clear that this is what the Binary and Serialise instances do. So this patch adds md5DigestBytes :: MD5Digest -> B.ByteString and haddock docs to point out the other options, of Show, Binary or Serialise.
1 parent 2df53d6 commit 2c83c63

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

Data/Digest/Pure/MD5.hs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module Data.Digest.Pure.MD5
3131
, md5
3232
, md5Update
3333
, md5Finalize
34+
, md5DigestBytes
3435
-- * Crypto-API interface
3536
, Hash(..)
3637
) where
@@ -39,6 +40,9 @@ import qualified Data.ByteString as B
3940
import qualified Data.ByteString.Lazy as L
4041
import Data.ByteString.Unsafe (unsafeDrop,unsafeUseAsCString)
4142
import Data.ByteString.Internal
43+
#if MIN_VERSION_binary(0,8,3)
44+
import Data.ByteString.Builder.Extra as B
45+
#endif
4246
import Data.Bits
4347
import Data.List
4448
import Data.Word
@@ -249,19 +253,42 @@ getNthWord n = right . G.runGet G.getWord32le . B.drop (n * sizeOf (undefined ::
249253
right x = case x of Right y -> y
250254
#endif
251255

256+
-- | The raw bytes of an 'MD5Digest'. It is always 16 bytes long.
257+
--
258+
-- You can also use the 'Binary' or 'S.Serialize' instances to output the raw
259+
-- bytes. Alternatively you can use 'show' to prodce the standard hex
260+
-- representation.
261+
--
262+
md5DigestBytes :: MD5Digest -> B.ByteString
263+
md5DigestBytes (MD5Digest h) = md5PartialBytes h
264+
265+
md5PartialBytes :: MD5Partial -> B.ByteString
266+
md5PartialBytes =
267+
toBs . (put :: MD5Partial -> Put)
268+
where
269+
toBs :: Put -> B.ByteString
270+
#if MIN_VERSION_binary(0,8,3)
271+
-- with later binary versions we can control the buffer size precisely:
272+
toBs = L.toStrict
273+
. B.toLazyByteStringWith (B.untrimmedStrategy 16 0) L.empty
274+
. execPut
275+
#else
276+
toBs = B.concat . L.toChunks . runPut
277+
-- note L.toStrict is only in newer bytestring versions
278+
#endif
279+
252280
----- Some quick and dirty instances follow -----
253281

254282
instance Show MD5Digest where
255283
show (MD5Digest h) = show h
256284

257285
instance Show MD5Partial where
258-
show (MD5Par a b c d) =
259-
let bs = runPut $ putWord32be d >> putWord32be c >>
260-
putWord32be b >> putWord32be a
286+
show md5par =
287+
let bs = md5PartialBytes md5par
261288
in foldl' (\str w -> let cx = showHex w str
262289
in if length cx < length str + 2
263290
then '0':cx
264-
else cx) "" (L.unpack bs)
291+
else cx) "" (B.unpack (B.reverse bs))
265292

266293
instance Binary MD5Digest where
267294
put (MD5Digest p) = put p

0 commit comments

Comments
 (0)