2012-02-29 50 views
7

我有一個文件路徑列表,並希望所有這些文件再次以sha1編碼的散列形式存儲在列表中。它應該儘可能一般,所以這些文件可以是文本以及二進制文件。現在我的問題是:Haskell中的SHA1編碼

  1. 應該使用哪些軟件包,爲什麼?
  2. 該方法的一致性如何?隨着我的意思是:如果有可能使用SHA1不同的程序編碼本身(例如SHA1SUM)不同的結果
+1

我無法判斷實現的質量,但在hackage中有幾個SHA1包的實現(部分密碼學)。通過定義SHA1,它可以處理文件的字節,因此無論是文本還是二進制文件都無關緊要,並且所有正確的實現都會爲同一文件提供相同的結果。 – 2012-02-29 16:36:18

回答

18

cryptohash包可能是最簡單的使用。只需將您的輸入讀入一個懶惰的 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使用不同的散列。

使用lazy ByteStrings避免了將整個文件一次加載到內存中,這在處理大文件時非常重要。