haskell 将ByteString精确打印为十六进制半字节

jfgube3f  于 2022-11-30  发布在  其他
关注(0)|答案(5)|浏览(178)

什么是一种习惯的方式来处理字节串,并漂亮地打印它的十六进制(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”,“7 e”],但字符串操作,而我更喜欢数字操作。我需要下拉到移位和掩码数值吗?

klr1opcd

klr1opcd1#

现在可以使用Data.ByteString.Builder了。要将ByteString打印成它的十六进制等价物(每个字节有两个十六进制数字,顺序正确,而且效率高),只需用途:

toLazyByteString . byteStringHex

toLazyByteString . lazyByteStringHex

这取决于输入的ByteString的风格。

ctehm74n

ctehm74n2#

我想详细说明一下max taldykin的答案(我已经投了赞成票),我认为这个答案太复杂了,没有必要用NoMonomorphismRestrictionprintfData.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]
osh3o9ms

osh3o9ms3#

像这样:

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

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

hex = foldl' (flip showHex) "" . B.unpack
7tofc5zh

7tofc5zh4#

您有["1","7e"]::[字符串] concat ["1", "7e"]"17e" :: String,它等于[字符]和['1','7','e'] :: [Char]
然后你可能会分裂成几部分字符串:

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

zsbz8rwp5#

如果你只想对ByteString进行常规的十六进制编码/解码,你可以使用内存包。他们把十六进制编码称为Base 16。

>>> let input = "Is 3 > 2?" :: ByteString
>>> let convertedTo base = convertToBase base input :: ByteString
>>> convertedTo Base16
"49732033203e20323f"

完整文档:https://hackage.haskell.org/package/memory-0.18.0/docs/Data-ByteArray-Encoding.html#t:Base

相关问题