
MD5> md5 (take 447 $ cycle [True, False, True, False, True])
(146018617,419045834,2338281671,4179882525)
MD5> md5 (take 449 $ cycle [True, False, True, False, True])
(3601628369,1310326814,2751960693,1362514509)
MD5> md5 (take 511 $ cycle [True, False, True, False, True])
(2264330280,2921290735,2761951796,3504581562)
MD5> md5 (take 513 $ cycle [True, False, True, False, True])
(4120376527,4030448340,1842259211,293161983)
MD5> md5s (take 447 $ cycle [True, False, True, False, True])
"3911b408ca21fa18c7585f8b1df223f9"
MD5> md5s (take 447 $ cycle [True, False, True, False, True])
"3911b408ca21fa18c7585f8b1df223f9"
MD5> md5s (take 511 $ cycle [True, False, True, False, True])
"28f0f686ef5b1fae340aa0a4baabe3d0"
MD5> md5s (take 513 $ cycle [True, False, True, False, True])
"cff497f5d4c23bf00ba5ce6dff4b7911"
MD5> md5i (take 447 $ cycle [True, False, True, False, True])
75857916336446301824658930015268905977
MD5> md5i (take 447 $ cycle [True, False, True, False, True])
75857916336446301824658930015268905977
MD5> md5i (take 511 $ cycle [True, False, True, False, True])
54420271240858347973075956822623118288
MD5> md5i (take 513 $ cycle [True, False, True, False, True])
276420197681555687768256992541883988241

> module Main where

> import MD5
> import Maybe

> main :: IO()
> main = do putStr "\n"
>           putStr "MD5 test suite\n"
>           putStr "==============\n\n"
>           test_0bit
>           test_1bit
>           test_8bit
>           test_16bit
>           test_21bit
>           test_32bit
>           test_440bit
>           test_447bit
>           test_448bit
>           test_449bit
>           test_456bit
>           test_504bit
>           test_511bit
>           test_512bit
>           test_513bit
>           test_520bit

> test_0bit :: IO()
> test_0bit = test "0 bit"
>                  (Just "")
>                  []
>                  (3649838548,78774415,2550759657,2118318316)
>                  "d41d8cd98f00b204e9800998ecf8427e"
>                  281949768489412648962353822266799178366

> test_1bit :: IO()
> test_1bit = test "1 bit"
>                  Nothing
>                  [True]
>                  (272066174,3209175982,751495693,2921214329)
>                  "7e663710ae2348bf0deaca2c79311eae"
>                  168013458602541801121410793648038157998

> test_8bit :: IO()
> test_8bit = test "8 bit"
>                  (Just "a")
>                  (c_to_bool 'a')
>                  (3111502092,2830561728,3801727793,1629910889)
>                  "0cc175b9c0f1b6a831c399e269772661"
>                  16955237001963240173058271559858726497

> test_16bit :: IO()
> test_16bit = test "16 bit"
>                   (Just "ab")
>                   (concat $ map c_to_bool "ab")
>                   (1140096536,3436257889,735854639,2699817106)
>                   "187ef4436122d1cc2f40dc2b92f0eba0"
>                   32560655549305688865853317129809488800

> test_21bit :: IO()
> test_21bit = test "21 bit"
>                   Nothing
>                   (take 21 $ cycle [True, False, True, False, True])
>                   (3016030143,592975423,115126882,2320915544)
>                   "bff7c4b33f16582362b2dc06585c568a"
>                   255169034072625008137368488973981996682

> test_32bit :: IO()
> test_32bit = test "32 bit"
>                   (Just "abcd")
>                   (concat $ map c_to_bool "abcd")
>                   (1282538722,2481858375,3441750933,523468590)
>                   "e2fc714c4727ee9395f324cd2e7f331f"
>                   301716283811389038011477436469853762335

> test_440bit :: IO()
> test_440bit = test "440 bit"
>                    (Just m_s)
>                    m_b
>                    (2129780455,1829200469,2963858748,3872126999)
>                    "e7def17e5562076d3ce5a8b017f8cbe6"
>                    308209254998797990860977056692741655526
>  where m_s = take 55 $ cycle "abcdefg"
>        m_b = take 440 $ cycle $ concat $ map c_to_bool "abcdefg"

> test_447bit :: IO()
> test_447bit = test "447 bit"
>                    Nothing
>                    (take 447 $ cycle [True, False, True, False, True])
>                    (146018617,419045834,2338281671,4179882525)
>                    "3911b408ca21fa18c7585f8b1df223f9"
>                    75857916336446301824658930015268905977

> test_448bit :: IO()
> test_448bit = test "448 bit"
>                    (Just m_s)
>                    m_b
>                    (272111924,677845269,2833319824,3656850596)
>                    "34193810151967289007e1a8a41cf7d9"
>                    69250800291397296307218994760733489113
>  where m_s = take 56 $ cycle "abcdefg"
>        m_b = take 448 $ cycle $ concat $ map c_to_bool "abcdefg"

> test_449bit :: IO()
> test_449bit = test "449 bit"
>                    Nothing
>                    (take 449 $ cycle [True, False, True, False, True])
>                    (3601628369,1310326814,2751960693,1362514509)
>                    "d17cacd61e001a4e759607a44d523651"
>                    278456001468069016726202533662103320145


> test_456bit :: IO()
> test_456bit = test "456 bit"
>                    (Just m_s)
>                    m_b
>                    (279449730,856127161,3308518469,3347659648)
>                    "8210a810b976073345fc33c5803b89c7"
>                    172886124971637048494467684822136097223
>  where m_s = take 57 $ cycle "abcdefg"
>        m_b = take 456 $ cycle $ concat $ map c_to_bool "abcdefg"

> test_504bit :: IO()
> test_504bit = test "504 bit"
>                    (Just m_s)
>                    m_b
>                    (2956572680,1313635985,3566901056,574489456)
>                    "08b839b0917e4c4e40979ad470033e22"
>                    11590376674781757343337222324479016482
>  where m_s = take 63 $ cycle "abcdefg"
>        m_b = take 504 $ cycle $ concat $ map c_to_bool "abcdefg"

> test_511bit :: IO()
> test_511bit = test "511 bit"
>                    Nothing
>                    (take 511 $ cycle [True, False, True, False, True])
>                    (2264330280,2921290735,2761951796,3504581562)
>                    "28f0f686ef5b1fae340aa0a4baabe3d0"
>                    54420271240858347973075956822623118288

> test_512bit :: IO()
> test_512bit = test "512 bit"
>                    (Just m_s)
>                    m_b
>                    (2109724156,489761275,3318408917,910478853)
>                    "fcd5bf7dfb29311dd5e6cac505ce4436"
>                    336075298090151865378817828545312474166
>  where m_s = take 64 $ cycle "abcdefg"
>        m_b = take 512 $ cycle $ concat $ map c_to_bool "abcdefg"

> test_513bit :: IO()
> test_513bit = test "513 bit"
>                    Nothing
>                    (take 513 $ cycle [True, False, True, False, True])
>                    (4120376527,4030448340,1842259211,293161983)
>                    "cff497f5d4c23bf00ba5ce6dff4b7911"
>                    276420197681555687768256992541883988241

> test_520bit :: IO()
> test_520bit = test "520 bit"
>                    (Just m_s)
>                    m_b
>                    (2047994787,3293532858,2497755399,2821287797)
>                    "a3eb117aba524fc407b9e094756f29a8"
>                    217884707599159781021720901460062841256
>  where m_s = take 65 $ cycle "abcdefg"
>        m_b = take 520 $ cycle $ concat $ map c_to_bool "abcdefg"

> test :: String -> Maybe String -> [Bool] -> ABCD -> String -> Integer -> IO()
> test text m_s b ans_abcd ans_s ans_i =
>  do putStr $ "Doing " ++ text                        ++ " test:\n"
>     putStr $ "------" ++ replicate (length text) '-' ++ "------\n"
>     case m_s of
>         Nothing -> return ()
>         Just s -> tesx "String" s ans_abcd ans_s ans_i
>     tesx "[Bool]" b ans_abcd ans_s ans_i

> tesx :: (MD5 a) => String -> a -> ABCD -> String -> Integer -> IO()
> tesx text m abcd s i =
>  do putStr $ text ++ ":" ++ replicate (12 - length text) ' '
>     putStr "md5 "
>     do_test $ md5 m == abcd
>     putStr " "
>     putStr "md5s "
>     do_test $ md5s m == s
>     putStr " "
>     putStr "md5i "
>     do_test $ md5i m == i
>     putStr "\n"
>     -----------------------------------
>     putStr $ text ++ "Mall:" ++ replicate (8 - length text) ' '
>     putStr "md5 "
>     res <- md5M monad_test_all m
>     do_test $ res == abcd
>     putStr " "
>     putStr "md5s "
>     res <- md5sM monad_test_all m
>     do_test $ res == s
>     putStr " "
>     putStr "md5i "
>     res <- md5iM monad_test_all m
>     do_test $ res == i
>     putStr "\n"
>     -----------------------------------
>     putStr $ text ++ "M8:" ++ replicate (10 - length text) ' '
>     putStr "md5 "
>     res <- md5M monad_test_8bit m
>     do_test $ res == abcd
>     putStr " "
>     putStr "md5s "
>     res <- md5sM monad_test_8bit m
>     do_test $ res == s
>     putStr " "
>     putStr "md5i "
>     res <- md5iM monad_test_8bit m
>     do_test $ res == i
>     putStr "\n"
>     -----------------------------------
>     putStr $ text ++ "M24:" ++ replicate (9 - length text) ' '
>     putStr "md5 "
>     res <- md5M monad_test_24bit m
>     do_test $ res == abcd
>     putStr " "
>     putStr "md5s "
>     res <- md5sM monad_test_24bit m
>     do_test $ res == s
>     putStr " "
>     putStr "md5i "
>     res <- md5iM monad_test_24bit m
>     do_test $ res == i
>     putStr "\n\n"

> do_test :: Bool -> IO()
> do_test b = putStr $ if b then "\027[32mOK.    \027[0m"
>                           else "\027[31mFAILED.\027[0m"


> monad_test_all :: (MD5 a) => a -> IO (a, a)
> monad_test_all m = return (anull, m)

> monad_test_8bit :: (MD5 a) => a -> IO (a, a)
> monad_test_8bit m = return (m', c)
>  where (c, m') = getDrop_bits 8 m

> monad_test_24bit :: (MD5 a) => a -> IO (a, a)
> monad_test_24bit m = return (m', c)
>  where (c, m') = getDrop_bits 24 m

> c_to_bool :: Char -> [Bool]
> c_to_bool 'a' = [False, True, True, False, False, False, False, True]
> c_to_bool 'b' = [False, True, True, False, False, False, True, False]
> c_to_bool 'c' = [False, True, True, False, False, False, True, True]
> c_to_bool 'd' = [False, True, True, False, False, True, False, False]
> c_to_bool 'e' = [False, True, True, False, False, True, False, True]
> c_to_bool 'f' = [False, True, True, False, False, True, True, False]
> c_to_bool 'g' = [False, True, True, False, False, True, True, True]
> c_to_bool _ = undefined

 h :: IO ABCD -> IO()
 h io_s = do s <- io_s
             putStr $ md5_display s

> takeDrop :: Int -> [a] -> ([a], [a])
> takeDrop _ [] = ([], [])
> takeDrop 0 xs = ([], xs)
> takeDrop n (x:xs) = (x:ys, zs)
>  where (ys, zs) = takeDrop (n-1) xs

