【问题标题】:Pretty print ByteString to hex nibble-wise漂亮的打印字节字符串到十六进制半字节
【发布时间】:2011-12-07 08:39:59
【问题描述】:

什么是处理字节串半字节并漂亮地打印其十六进制 (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"] 进行字符串操作,而我更愿意进行数字操作。我是否需要下拉到移位和屏蔽数值?

【问题讨论】:

    标签: haskell hex pretty-print bytestring


    【解决方案1】:

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

    toLazyByteString . byteStringHex
    

    toLazyByteString . lazyByteStringHex
    

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

    【讨论】:

      【解决方案2】:

      我想详细说明一下 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]
      

      【讨论】:

      • 你会在这里弄乱结果,因为showHex 不会填充到 2。
      • @Peaker 是对的,这个解决方案是不正确的。它切断任何前导零。 crockeea 在底部的答案是正确的。
      【解决方案3】:

      类似这样的:

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

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

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

      【讨论】:

      • 当然foldl' 版本以相反的顺序打印字节,“小端”样式。
      【解决方案4】:

      你有["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]]
      

      【讨论】:

      • Data.List.Split.splitEvery 1 == map (:[])
      猜你喜欢
      • 1970-01-01
      • 2014-05-26
      • 2015-01-17
      • 2012-01-24
      • 2013-08-09
      • 2012-09-25
      • 2013-10-13
      • 2020-12-28
      相关资源
      最近更新 更多