2012-02-29 9 views
7

Mam listę ścieżek do plików i chcę, aby wszystkie te pliki zostały ponownie zapisane jako sha1 zaszyfrowane na liście. Powinien być tak ogólny, jak to możliwe, więc pliki mogą być zarówno tekstowe, jak i binarne. A teraz moje pytania to:Kodowanie SHA1 w Haskell

  1. Jakie pakiety powinny być używane i dlaczego?
  2. Jak konsekwentne jest podejście? Mając to znaczy: jeśli nie mogą być różne wyniki z różnych programów za pomocą SHA-1 kodowania się (np sha1sum)
+1

Nie mogę ocenić jakości implementacji, ale istnieje kilka implementacji SHA1 w pakietach hackage (sekcja Cryptography). Definicja SHA1 działa na bajtach pliku, więc niezależnie od tego, czy jest to tekst czy plik binarny, nie ma znaczenia, a wszystkie poprawne implementacje dają taki sam wynik dla tego samego pliku. –

Odpowiedz

18

Pakiet cryptohash jest prawdopodobnie najprostszy w użyciu. Po prostu odczytaj dane wejściowe do leniwego ByteString i użyj funkcji hashlazy, aby uzyskać ByteString z wynikowym hashem. Oto mały przykładowy program, którego możesz użyć do porównania wyjścia z danymi z 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() 

Od tego odczytuje bajty, a nie znaki, nie powinno być żadnych problemów kodowania i powinien on zawsze daje taki sam wynik jak sha1sum:

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

Działa to także dla każdego z mieszań obsługiwanych przez pakiet cryptohash. Po prostu zmień import do np. Crypto.Hash.SHA256, aby użyć innego skrótu.

Używanie leniwych ByteStrings pozwala uniknąć jednoczesnego ładowania całego pliku do pamięci, co jest ważne podczas pracy z dużymi plikami.