2011-12-07 4 views
9

bytestring을 16 진법 (16 진수 (0-F) 표현)으로 인쇄하는 관용적 인 방법은 무엇입니까?ByteString을 16 진수로 니블하게 인쇄합니다.

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

은 추가 작업에 따라 어떤,

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

하지만 내가 정말 원하는 것은

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

내가 [ "1"을로 찾으면 수있는 더 좋은 방법은

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

또는이다 , "7e"] 그러나 그 문자열 조작은 오히려 숫자 조작. 숫자 값을 이동 및 마스킹해야합니까?

답변

10

. 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] 
+1

+1, 그냥 'concat. map' =='concatMap' –

+8

'showHex'가 2로 채워지지 않기 때문에 결과가 엉망이됩니다. – Peaker

+0

@Peaker가 맞습니다.이 해결책은 잘못되었습니다. 그것은 앞에 오는 0을 자릅니다. crockeea의 답변은 정확합니다. –

3

당신은 ["1","7e"] :: [문자열] concat ["1", "7e"]가 [숯불] 같고 ['1','7','e'] :: [Char] 같다 "17e" :: String입니다 있습니다.

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

'Data.List.Split.splitEvery 1' =='map (: [])' –

4

somethig에이 같은 :

{-# 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을로 대체해야합니다.(게으름은 여기에 필요하지 않으므로) :

hex = foldl' (flip showHex) "" . B.unpack 
나는 복잡 이상-생각하는 (내가 upvoted 것을) 최대 taldykin의 대답에 정교하고 싶습니다
+0

물론'foldl'' 버전은 역순으로 "little-endian"스타일로 바이트를 출력합니다. – crockeea

5

이제 Data.ByteString.Builder를 사용할 수 있습니다

여기 내 버전입니다. (효율적으로 올바른 순서로, 바이트 당 두 개의 16 진수로 등)의 헥사 값에 ByteString을 인쇄하려면 사용

toLazyByteString . byteStringHex 

또는

toLazyByteString . lazyByteStringHex 

가 따라 ByteString의 어느 맛에 당신 입력으로 가지고있다.

관련 문제