【问题标题】:SHA1 encoding in HaskellHaskell 中的 SHA1 编码
【发布时间】:2012-02-29 16:21:32
【问题描述】:

我有一个文件路径列表,并希望所有这些文件再次作为 sha1 编码哈希存储在列表中。它应该尽可能通用,因此文件可以是文本文件也可以是二进制文件。现在我的问题是:

  1. 应该使用哪些软件包以及为什么?
  2. 这种方法的一致性如何?我的意思是:如果使用 sha1 对自身进行编码(例如 sha1sum)的不同程序可能会有不同的结果

【问题讨论】:

  • 我无法判断实现的质量,但在 hackage 的包中有几种 SHA1 实现(密码学部分)。根据 SHA1 的定义,它作用于文件的字节,所以无论是文本还是二进制都无所谓,所有正确的实现对同一个文件给出相同的结果。

标签: haskell cryptography sha1


【解决方案1】:

cryptohash 包可能是最简单易用的。只需将您的输入读入惰性1 ByteString 并使用hashlazy 函数获取带有结果哈希的ByteString。这是一个小示例程序,您可以使用它来将输出与sha1sum 的输出进行比较。

import Crypto.Hash.SHA1 (hashlazy)
import qualified Data.ByteString as Strict
import qualified Data.ByteString.Lazy as Lazy
import System.Process (system)
import Text.Printf (printf)

hashFile :: FilePath -> IO Strict.ByteString
hashFile = fmap hashlazy . Lazy.readFile 

toHex :: Strict.ByteString -> String
toHex bytes = Strict.unpack bytes >>= printf "%02x"

test :: FilePath -> IO ()
test path = do
  hashFile path >>= putStrLn . toHex
  system $ "sha1sum " ++ path
  return ()

由于它读取的是纯字节,而不是字符,因此应该没有编码问题,并且它应该始终给出与 sha1sum 相同的结果:

> test "/usr/share/dict/words"
d6e483cb67d6de3b8cfe8f4952eb55453bb99116
d6e483cb67d6de3b8cfe8f4952eb55453bb99116  /usr/share/dict/words

这也适用于 cryptohash 包支持的任何散列。只需将导入更改为例如Crypto.Hash.SHA256 使用不同的哈希值。

1 使用惰性字节字符串可以避免一次将整个文件加载到内存中,这在处理大文件时很重要。

【讨论】:

    【解决方案2】:

    至于@hammar 的回答,这很好,但您可以使用Base16 library 而不是自己制作toHex

    import qualified Data.ByteString.Base16 as B16
    hashFile path >>= putStrLn . B16.encode
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 2013-07-08
      相关资源
      最近更新 更多