public
Created

Get the hex representation of a ByteString

  • Download Gist
hex.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as S8
import Data.Bits
import System.Environment (getArgs)
import qualified Numeric
import Test.QuickCheck (quickCheck)
import Test.QuickCheck.Arbitrary (Arbitrary (..))
import Criterion.Main
 
main :: IO ()
main = do
args <- getArgs
case args of
["test"] -> test
[] -> bench'
_ -> error "Usage: hex [test]"
 
test :: IO ()
test = quickCheck $ \bs -> simple bs == unfoldrN_MS1 bs
 
instance Arbitrary S.ByteString where
arbitrary = fmap S.pack arbitrary
 
bench' :: IO ()
bench' = defaultMain
[ bench "simple" $ whnf simple sample
, bench "unfoldrN_MS1" $ whnf unfoldrN_MS1 sample
]
where
sample = S.replicate 5000 29
 
simple :: S.ByteString -> S.ByteString
simple =
S.concatMap $ \c -> S8.pack $ pad $ Numeric.showHex c []
where
pad [x] = ['0', x]
pad s = s
 
unfoldrN_MS1 :: S.ByteString -> S.ByteString
unfoldrN_MS1 bs0 =
fst $ S.unfoldrN (S.length bs0 * 2) go (Left bs0)
where
go (Left bs) =
case S.uncons bs of
Nothing -> Nothing
Just (w, bs') ->
let w1 = w `shiftR` 4
w2 = w .&. 15
c1 = toC w1
c2 = toC w2
in Just (c1, Right (c2, bs'))
go (Right (c, bs)) = Just (c, Left bs)
 
toC w
| w < 10 = w + 48
| otherwise = w + 87

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.