Skip to content

Instantly share code, notes, and snippets.

@hyphenrf
Last active May 9, 2021 00:45
Show Gist options
  • Save hyphenrf/4f18bc8d7c0a36b872e507db054eed7b to your computer and use it in GitHub Desktop.
Save hyphenrf/4f18bc8d7c0a36b872e507db054eed7b to your computer and use it in GitHub Desktop.
a utility equivalent to `xxd -r -ps` for systems with limited xxd implementations
{-# language OverloadedStrings #-}
import Prelude hiding (getLine, putStr, filter, length, take, drop)
import Data.ByteString
import Data.Maybe
main = do
ln <- getLine
putStr $ f ln -- putStr and getLine from ByteString
where
f = pack -- [Word8] -> ByteString
. mapMaybe readchk -- get byte chunk values. single nibble is dropped hence Maybe
. chunksOf 2 -- hex byte chunks
. filter (>0x20) -- drop whitespace
readchk bs | length bs == 2 = Just $ look a * 16 + look b
| otherwise = Nothing -- drop the trailing nibble (xxd behaviour)
where
[a, b] = unpack bs -- this is always a safe match
die = errorWithoutStackTrace
look n
| not $ n > 0x2f && n < 0x3a || n > 0x40 && n < 0x47 || n > 0x60 && n < 0x67
= die "invalid input, expecting hexadecimal"
| n < 0x40 = n - 0x30
| n < 0x60 = n - 0x37
| otherwise = n - 0x57
chunksOf n "" = []
chunksOf n bs = take n bs : chunksOf n (drop n bs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment