简体   繁体   中英

What is the Haskell equivalent of Python's hexlify and unhexlify?

I have code that looks a little like

module Lib where

import Data.ByteString (ByteString)
import Data.ByteString.Lazy (fromStrict)
import Data.Digest.Pure.SHA (sha1, showDigest)

hash :: ByteString -> String
hash bstring = showDigest $ sha1 $ fromStrict bstring

which gives me a hexadecimal string representation of a SHA1 hash. How would I convert between this hexadecimal representation and the binary representation? In python I would use binascii.hexlify and binascii.unhexlify . For example:

'95d09f2b10159347eece71399a7e2e907ea3df4f' <=> '\x95\xd0\x9f+\x10\x15\x93G\xee\xceq9\x9a~.\x90~\xa3\xdfO'

I normally call this base-16 encoding, and it is also available in Python as base64.b16decode() and base64.b16encode() . The terms "hexlify" and "unhexlify" seem to be a bit idiosyncratic.

Using these search terms, I was able to find base16-bytestring in Hackage. It consumes and returns ByteString , not String , so you will need to pack if you have String .

Here is how you use it. You can see that it has a slightly different interface, and Haskell escapes strings differently, but it gives the same results that you give in your example.

> decode "95d09f2b10159347eece71399a7e2e907ea3df4f"
("\149\208\159+\DLE\NAK\147G\238\206q9\154~.\144~\163\223O","")
> encode "\x95\xd0\x9f+\x10\x15\x93G\xee\xceq9\x9a~.\x90~\xa3\xdfO"
"95d09f2b10159347eece71399a7e2e907ea3df4f"

I couldn't find a package that did this for me, so I rolled my own:

import Data.ByteString (pack, unpack)
import Numeric (showHex, readHex)

unhexlify :: String -> ByteString
unhexlify hexstr = let bytes = pairs hexstr
                       nums  = map fst $ concatMap readHex bytes
                   in pack nums

hexlify :: ByteString -> String
hexlify binstr = let nums = unpack binstr
                     hex  = map showHex nums
                 in foldr ($) "" hex

pairs :: String -> [String]
pairs [] = []
pairs (x:y:xs) = [x,y]:pairs xs
from encodings.hex_codec import binascii

value = binascii.a2b_hex('95d09f2b10159347eece71399a7e2e907ea3df4f')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM