| 756 | |
| 757 | == Haskell == |
| 758 | {{{ |
| 759 | import IO(bracket) |
| 760 | import System.Environment(getArgs) |
| 761 | import System.IO(openBinaryFile,hClose,hFileSize,hSeek,IOMode(ReadMode),SeekMode(AbsoluteSeek,SeekFromEnd)) |
| 762 | import qualified Data.ByteString.Lazy as L(hGet,unpack) |
| 763 | import Data.Binary.Get(runGet,getWord64le) |
| 764 | import Data.Binary.Put(runPut,putWord64le) |
| 765 | import Data.Word(Word64) |
| 766 | import Control.Monad(foldM) |
| 767 | import Data.Bits.Utils(w82s) |
| 768 | import Data.Hex(hex) |
| 769 | |
| 770 | shortsum :: FilePath -> IO Word64 |
| 771 | shortsum filename = bracket (openBinaryFile filename ReadMode) hClose $ \h -> do |
| 772 | fs <- hFileSize h |
| 773 | hSeek h AbsoluteSeek 0 ; begin <- L.hGet h chunksize |
| 774 | hSeek h SeekFromEnd (-(toInteger chunksize)) ; end <- L.hGet h chunksize |
| 775 | return $ (flip runGet $ begin) $ chunksum $ (flip runGet $ end) (chunksum . fromInteger $ fs) |
| 776 | where |
| 777 | chunksize = 0x10000 |
| 778 | chunksum n = foldM (\a _ -> getWord64le >>= return . (+a)) n [1..(chunksize`div`8)] |
| 779 | |
| 780 | main :: IO () |
| 781 | main = do |
| 782 | args <- getArgs |
| 783 | let fn = head $ args |
| 784 | p <- shortsum fn |
| 785 | putStrLn $ "The hash of file " ++ fn ++ ": " ++ (hex $ w82s $ reverse (L.unpack $ runPut $ putWord64le p)) |
| 786 | }}} |