Il pacchetto cryptohash è probabilmente il più semplice da utilizzare. Basta leggere l'input in un pigro ByteString e utilizzare la funzione hashlazy
per ottenere un ByteString con l'hash risultante. Ecco un piccolo programma di esempio che puoi utilizzare per confrontare l'output con quello di 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()
Dal momento che questa legge byte strisciamento, non personaggi, non ci dovrebbero essere problemi di codifica e dovrebbe sempre dare lo stesso risultato di sha1sum
:
> test "/usr/share/dict/words"
d6e483cb67d6de3b8cfe8f4952eb55453bb99116
d6e483cb67d6de3b8cfe8f4952eb55453bb99116 /usr/share/dict/words
Questo funziona anche per una qualsiasi delle hash supportati da il pacchetto criptohash. Basta cambiare l'importazione ad es. Crypto.Hash.SHA256
per utilizzare un hash diverso.
L'utilizzo di ByteString pigro evita il caricamento dell'intero file in memoria in una volta, operazione importante quando si lavora con file di grandi dimensioni.
Non riesco a giudicare la qualità delle implementazioni, ma ci sono diverse implementazioni di SHA1 in pacchetti su hackage (sezione Cryptography). Con la definizione di SHA1, funziona sui byte del file, quindi se il testo o il binario non contano e tutte le implementazioni corrette danno lo stesso risultato per lo stesso file. –