#### EG Information

 Main Index EG Manual Disclaimer Legal Information Hall of Fame Hall of Shame Member Rankings Members List Meet the Staff Hacker's Home Page IRC Flash Chat

#### Training Missions

 Read Me First Basic Skills Realistic Scenarios Cryptography Software Cracking Linux ELF Binary Cracking Logical Thinking Programming Captcha Cracking Patching Steganography Deface This Wall /dev/null /dev/urandom /dev/extra

#### Knowledge Bank

 Discussion Forums Exploit Database PasteBin RSS Feeds Articles / Tutorials Videos Online EG MP3 Player Downloads Tools

#### Pimp Us Out!

 Has Enigma Group Helped You? Then Help Us By Advertising For Us. Place One Of The Following Images On Your Site And Create A Link Back To Enigma Group.

# The Caesar Cipher

By: ParadoxMAI  -  Date Submitted: 2011-12-18 20:23:56

`import Data.Charimport Data.Listimport Test.QuickCheck import Data.Functionimport Data.Maybe  rotate :: Int -> [Char] -> [Char]rotate k list | 0 <= k && k <= length list = drop k list ++ take k list              | otherwise = error "Argument to rotate too large or too small" prop_rotate :: Int -> String -> Boolprop_rotate k str = rotate (l - m) (rotate m str) == str                        where l = length str                              m = if l == 0 then 0 else k `mod` l -- prop_rotate rotates a list of lenght l first an arbitrary number m times,--  and then rotates it l-m times; together (m + l - m = l) it rotates it all--  the way round, back to the original list---- to avoid errors with 'rotate', m should be between 0 and l; to get m--  from a random number k we use k `mod` l (but then l can't be 0,--  since you can't divide by 0)  alphabet = ['A'..'Z'] makeKey :: Int -> [(Char, Char)]makeKey k = zip alphabet (rotate k alphabet) .lookUp :: Char -> [(Char, Char)] -> CharlookUp ch [] = chlookUp ch ((key,val):restKey)    | key == ch = val    | otherwise = lookUp ch restKey -- alternative solution with list-comprehension---- lookUp ch xs = head ([ y | (x,y) <- xs, x == ch] ++ [ch])  encipher :: Int -> Char -> Charencipher k ch = lookUp ch (makeKey k)  normalize :: String -> Stringnormalize [] = []normalize (ch:str)    | isAlpha ch = toUpper ch : normalize str    | isDigit ch = ch : normalize str    | otherwise  = normalize str  encipherStr :: Int -> String -> StringencipherStr k str = [encipher k ch | ch <- normalize str]  reverseKey :: [(Char, Char)] -> [(Char, Char)]reverseKey key = [(b, a) | (a, b) <- key]  decipher :: Int -> Char -> Chardecipher k ch = lookUp ch (reverseKey (makeKey k)) decipherStr :: Int -> String -> StringdecipherStr k str = [decipher k ch | ch <- str]  prop_cipher :: Int -> String -> Boolprop_cipher k str = decipherStr l (encipherStr l str) == normalize str  where l = k `mod` 26  contains :: String -> String -> Boolcontains _ [] = Truecontains [] _ = Falsecontains str substr =     isPrefixOf substr str || contains (tail str) substr .candidates :: String -> [(Int, String)]candidates str = [(i, decipherStr i str) | i <- [0..25], candidate (decipherStr i str)]    where candidate str = str `contains` "AND" || str `contains` "THE"  splitEachFive :: String -> [String]splitEachFive xs | length xs > 5 = take 5 xs : splitEachFive (drop 5 xs)                 | otherwise     = [ fillToFive xs ] fillToFive :: String -> StringfillToFive xs = xs ++ replicate (5 - length xs) 'X' -- An alternative solution demonstrating 'repeat'fillToFive' :: String -> StringfillToFive' xs = take 5 (xs ++ repeat 'X') prop_transpose :: String -> Boolprop_transpose xs = ys == transpose (transpose ys)    where      ys = splitEachFive xs encrypt :: Int -> String -> Stringencrypt n str = concat (transpose (splitEachFive (encipherStr n str)))   splitFiveWays :: String -> [String]splitFiveWays xs | n `mod` 5 == 0 = splitEach (n `div` 5) xs                 | otherwise      = error "splitFiveWays: not a multiple of 5"                 where n = length xs splitEach :: Int -> String -> [String]splitEach _ [] = []splitEach n xs = take n xs : splitEach n (drop n xs) decrypt :: Int -> String -> Stringdecrypt n str = concat (transpose (splitFiveWays (decipherStr n str))) -- Increment a frequency in a character frequency list.incAsc :: Char -> [(Char, Int)] -> [(Char, Int)]incAsc c [] = [(c,1)]incAsc c ((d,n) : xs) | c == d    = (d, n+1) : xs                      | otherwise = (d, n)   : incAsc c xs countFreqs :: String -> [(Char, Int)]countFreqs xs = count xs []    where count [] freqs       = freqs          count (x : xs) freqs = count xs (incAsc x freqs) -- Rank the candidates which might decipher to 'E'freqCandidates :: [Char] -> [Int]freqCandidates xs = [ (ord c - ord 'E') `mod` 26 | (c, _) <- freqChars ]    where freqChars     = sortBy p (countFreqs xs)          p (_,m) (_,n) = compare n m freqDecipher :: String -> [String]freqDecipher xs = [ decrypt n xs | n <- freqCandidates xs ]`