12

什么是处理字节串半字节并漂亮地打印其十六进制(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

4 回答 4

15

您现在可以使用Data.ByteString.Builder. 要将 a 打印ByteString到其十六进制等效项(每个字节有两个十六进制数字,以正确的顺序且高效),只需使用:

toLazyByteString . byteStringHex

或者

toLazyByteString . lazyByteStringHex

取决于ByteString您输入的口味。

于 2016-02-24T14:29:26.443 回答
9

我想详细说明 max taldykin 的回答(我已赞成),我认为这过于复杂。不需要NoMonomorphismRestriction,printfData.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]
于 2011-12-07T13:37:44.843 回答
4

像这样的东西:

{-# 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']"

更新哦,有一个愚蠢的内存泄漏:当然你应该替换foldrfoldl'(因为这里不需要懒惰):

hex = foldl' (flip showHex) "" . B.unpack
于 2011-12-07T09:22:33.027 回答
3

你有["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]]
于 2011-12-07T09:19:41.470 回答