Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty print ByteString to hex nibble-wise

What's an idiomatic way of treating a bytestring nibblewise and pretty printing its hexadecimal (0-F) representation?

putStrLn . show . B.unpack
-- [1,126]

Which, upon further work

putStrLn . show . map (\x -> N.showIntAtBase 16 (DC.intToDigit) x "") . B.unpack
["1","7e"]

But what I really want is

["1","7","e"]

Or better yet

['1','7','e']

I could munge up ["1","7e"] but that string manipulation whereas I'd rather do numeric manipulation. Do I need to drop down to shifting and masking numeric values?

like image 544
xrl Avatar asked Dec 07 '11 08:12

xrl


2 Answers

You can now use Data.ByteString.Builder. To print a ByteString to its hex equivalent (with two hex digits per byte, in the right order, and efficiently), simply use:

toLazyByteString . byteStringHex

or

toLazyByteString . lazyByteStringHex

depending on which flavor of ByteString you have as input.

like image 77
crockeea Avatar answered Oct 13 '22 11:10

crockeea


I'd like to elaborate on max taldykin's answer (that I have upvoted), which I think is over-complicated. There is no need for NoMonomorphismRestriction, printf or Data.List.

Here is my version:

import qualified Data.ByteString as B
import Numeric (showHex)

prettyPrint :: B.ByteString -> String
prettyPrint = concat . map (flip showHex "") . B.unpack

main :: IO ()
main = putStrLn . prettyPrint . B.pack $ [102, 117, 110]
like image 34
lbolla Avatar answered Oct 13 '22 13:10

lbolla