Довольно распечатать ByteString в шестнадцатеричном виде - PullRequest
11 голосов
/ 07 декабря 2011

Что такое идиоматический способ обработки байтовой строки по кусочкам и красивой печати ее шестнадцатеричного (0-F) представления?

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

Какой, при дальнейшей работе

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

Но что ядействительно хочу это

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

Или еще лучше

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

Я мог бы запутаться ["1", "7e"], но это - манипулирование строками, тогда как я бы предпочел числовые манипуляции.Нужно ли переходить к смещению и маскированию числовых значений?

Ответы [ 4 ]

11 голосов
/ 24 февраля 2016

Теперь вы можете использовать Data.ByteString.Builder. Чтобы вывести ByteString в его шестнадцатеричный эквивалент (с двумя шестнадцатеричными цифрами на байт, в правильном порядке и эффективно), просто используйте:

toLazyByteString . byteStringHex

или

toLazyByteString . lazyByteStringHex

в зависимости от того, какой аромат ByteString вы используете в качестве ввода.

11 голосов
/ 07 декабря 2011

Я бы хотел уточнить ответ Макса Талдыкина (за который я проголосовал), который, как мне кажется, слишком сложен.Нет необходимости в NoMonomorphismRestriction, printf или Data.List.

Вот моя версия:

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]
4 голосов
/ 07 декабря 2011

Примерно так:

{-# LANGUAGE NoMonomorphismRestriction #-}

import qualified Data.ByteString as B
import Text.Printf
import Data.List
import Numeric

hex = foldr showHex "" . B.unpack
list = printf "[%s]" . concat . intersperse "," . map show

Тест:

> let x = B.pack [102,117,110]
> list . hex $ x
"['6','6','7','5','6','e']"

Upd О, есть глупая утечка памяти: конечно, вы должны заменить foldr с foldl' (потому что лень здесь не требуется):

hex = foldl' (flip showHex) "" . B.unpack
3 голосов
/ 07 декабря 2011

У вас есть ["1","7e"] :: [String] concat ["1", "7e"] равно "17e" :: String, что равно [Char] и равно ['1','7','e'] :: [Char].

Чем вы можете разбить эту строку на куски:

> Data.List.Split.splitEvery 1 . concat $ ["1", "7e"]
["1","7","e"]
it :: [[Char]]
...