我需要HEX格式的字符串的sha1哈希值。这是基本代码:
import Data.ByteString.UTF8
import Crypto.Hash.SHA1 (hash)
toArgs :: String -> (String,String)
toArgs str = let h = show . hash . fromString $ str
in (str,h)
哪个产生散列,但是形式如下:
$ toArgs "Hejsan"
("Hejsan","\"A\\CAN]]\\131\\168\\210|\\n\\NUL\\NAK\\187j\\181Q\\STX\\146o\\fP\"")
我尝试使用printf将其转换为HEX:
import Data.ByteString.UTF8
import Crypto.Hash.SHA1 (hash)
import Text.Printf (printf)
toArgs :: String -> (String,String)
toArgs str = let h = printf "%02x" $ show . hash . fromString $ str
in (str,h)
编译,但在执行时抛出异常:
toArgs "Hejsan"
("Hejsan","*** Exception: Printf.printf: bad argument
有什么想法吗?
答案 0 :(得分:3)
Haskell中printf
的特定实现并不是类型安全的。你遇到了这个问题。 %x
说明符需要一个数字,但是你要传递一个字符串。
假设您正在使用cryptohash
包,获取十六进制表示的最佳方法是使用Crypto.Hash
中的函数,类似这样:
import Crypto.Hash
sha1Hex :: ByteString -> ByteString
sha1Hex s = digestToHexByteString (hash s :: Digest SHA1)
答案 1 :(得分:2)
我建议使用base16-bytestring包。请注意,您需要将String
变为ByteString
,我建议将其作为UTF8编码。总而言之,这看起来像是:
Data.Text.unpack . decodeUtf8 . Base16.encode . encodeUtf8 . Data.Text.pack
如果你坚持使用Text
代替String
(我建议),你可以不用unpack
和pack
。