将 ByteString 漂亮地打印为十六进制半字节

发布于 2024-12-19 23:16:04 字数 421 浏览 3 评论 0原文

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

我可以 munge up [“1”,“7e”] 但字符串操作,而我宁愿进行数字操作。我是否需要向下移动和屏蔽数值?

What's an idiomatic way of treating a bytestring nibblewise and pretty printing its hexadecimal (0-F) representation?

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

Which, upon further work

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

But what I really want is

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

Or better yet

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

I could munge up ["1","7e"] but that string manipulation whereas I'd rather do numeric manipulation. Do I need to drop down to shifting and masking numeric values?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

倾城泪 2024-12-26 23:16:04

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

toLazyByteString . byteStringHex

toLazyByteString . lazyByteStringHex

根据您使用的 ByteString 风格有作为输入。

You can now use Data.ByteString.Builder. To print a ByteString to its hex equivalent (with two hex digits per byte, in the right order, and efficiently), simply use:

toLazyByteString . byteStringHex

or

toLazyByteString . lazyByteStringHex

depending on which flavor of ByteString you have as input.

游魂 2024-12-26 23:16:04

我想详细说明马克斯·塔尔迪金的答案(我已投赞成票),我认为这个答案过于复杂。不需要 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]

I'd like to elaborate on max taldykin's answer (that I have upvoted), which I think is over-complicated. There is no need for NoMonomorphismRestriction, printf or Data.List.

Here is my version:

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]
污味仙女 2024-12-26 23:16:04

像这样的东西:

{-# 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哦,有一个愚蠢的内存泄漏:当然你应该用foldl'替换foldr(因为懒惰是此处不需要):

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

Somethig like this:

{-# 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

Test:

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

Upd Oh, there is a stupid memory leak: of course you should replace foldr with foldl' (because laziness is not required here):

hex = foldl' (flip showHex) "" . B.unpack
嘿咻 2024-12-26 23:16:04

您有 ["1","7e"] :: [String]
concat ["1", "7e"]"17e" :: String ,它等于 [Char] 且等于 ['1',' 7','e'] :: [字符]

您可以将该字符串分成几部分:

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

You have ["1","7e"] :: [String]
concat ["1", "7e"] is "17e" :: String which is equal to [Char] and equal to ['1','7','e'] :: [Char].

Than you may split that String into pieces:

> Data.List.Split.splitEvery 1 . concat $ ["1", "7e"]
["1","7","e"]
it :: [[Char]]
坐在坟头思考人生 2024-12-26 23:16:04

如果您只想对 ByteStrings 进行常规的十六进制编码/解码,则可以使用内存包。他们将十六进制编码称为 Base16。

>>> 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

If you just want a regular hex en/decoding of ByteStrings, you can use the memory package. They call the hex encoding Base16.

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

Full documentation: https://hackage.haskell.org/package/memory-0.18.0/docs/Data-ByteArray-Encoding.html#t:Base

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文