TigerHash-0.2: examples/testtiger.hs
{-
DC++ protocl utls for GHC
Copyright (C) 2009 Nikolay Orlyuk (virkony _at_ gmail _dot_ com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-}
{-# OPTIONS_GHC -O2 -fignore-asserts -fspec-constr #-}
import Data.Digest.TigerHash
import Data.Digest.TigerHash.ByteString
import Data.Digest.TigerHash.Internal
import Text.Printf
import Data.Word
import Data.Bits
import qualified Data.ByteString as B
import qualified Data.ByteString.Internal as S
import qualified Data.ByteString.Char8 as BC
import Foreign.Ptr
import Foreign.ForeignPtr
import Control.Monad
import System.Posix.Process
iterations = 200000::Word32
explodeBytes :: (Integral n, Bits n) => n -> [Word8]
explodeBytes x = walk (bitSize x `div` 8) x where
walk 0 _ = []
walk p x = (fromIntegral x : walk (p-1) (x `shiftR` 8))
hash s = do
let th = tigerHash (BC.pack s)
putStr $ "Hash of \"" ++ s ++ "\":\n\t" ++ hexTigerHash th ++ "\n"
main = do
-- Hash of short strings
hash ""
hash "abc"
hash "Tiger"
-- Hash of 512-bit strings
hash "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
hash "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
hash "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
-- Hash of two-block strings strings
hash "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge."
hash "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996."
hash "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
-- Hash of a 64K byte string
let buffer = B.pack [fromIntegral i | i <- [0 .. 65535]]
buffer `seq` return () -- force calc
let th = tigerHash buffer
putStr $ "Hash of a 64K-byte string:\n\t" ++ hexTigerHash th ++ "\n"
putStr "Calculating speed...\n"
t1 <- getProcessTimes
let (p, s, bufSz) = S.toForeignPtr buffer in withForeignPtr p $ \p_ -> do
let bufPtr = (p_ `plusPtr` s)
withTigerContext $ \ctx_ -> do
let body = do
resetContext ctx_
updateContext ctx_ bufPtr bufSz
finalizeContext ctx_
mapM_ (const body) [1 .. fromIntegral iterations]
t2 <- getProcessTimes
let rate = fromIntegral iterations * fromIntegral (B.length buffer) * 8 / toRational (userTime t2 - userTime t1)
let humanRate = walk ["bit","KBit", "MBit", "GBit", "TBit"] where
walk [x] r = (r, x)
walk (x:xs) r | r < 512 = (r, x)
| otherwise = walk xs (r / 1024)
let (hRate,hSym) = humanRate rate
printf "rate = %.3f %s/s\n" ((fromRational hRate)::Double) hSym