#!/usr/bin/runghc module CaesarCipher (encryptString, decryptString) where import Data.List import Data.Maybe () import System.Random (randomRIO) import Test.QuickCheck symbolSet :: String symbolSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?." m = length symbolSet -- | -- >>> encodeChar 'A' -- Just 0 encodeChar :: Char -> Maybe Int encodeChar symbol = elemIndex symbol symbolSet -- | -- >>> decodeChar 0 -- 'A' decodeChar :: Int -> Char decodeChar index = symbolSet !! index -- | -- >>> addKeyPoint 1 4 -- 5 -- | -- >>> addKeyPoint 1 65 -- 0 addKeyPoint :: Int -> Int -> Int addKeyPoint key codePoint = mod (codePoint + key) m -- | -- >>> subKeyPoint 1 5 -- 4 -- | -- >>> subKeyPoint 1 0 -- 65 subKeyPoint :: Int -> Int -> Int subKeyPoint key codePoint = mod (codePoint - key) m -- | -- >>> encryptChar 1 'A' -- 'B' encryptChar :: Int -> Char -> Char encryptChar key c = case encodeChar c of Nothing -> c Just codePoint -> decodeChar (addKeyPoint key codePoint) -- | -- >>> decryptChar 1 'B' -- 'A' decryptChar :: Int -> Char -> Char decryptChar key c = case encodeChar c of Nothing -> c Just codePoint -> decodeChar (subKeyPoint key codePoint) -- | -- >>> encryptString 1 "zed." -- "1feA" encryptString :: Int -> String -> String encryptString key = map (encryptChar key) -- Eta reduced from this: -- encryptString key message = map (encryptChar key) message -- | -- >>> decryptString 1 "1feA" -- "zed." decryptString :: Int -> String -> String decryptString key = map (decryptChar key) -- Eta reduced from this: -- decryptString key message = map (decryptChar key) message -- | -- >>> quickCheck test -- +++ OK, passed 100 tests. test :: Int -> String -> Bool test key message = message == (decryptString key . encryptString key) message keyGen :: IO Int keyGen = randomRIO (1, m) :: IO Int main :: IO () main = do let message = "All human beings have three lives: public, private, and secret. Gabriel Garcia Marquez" -- let key = 13 key <- keyGen putStrLn ("Your key was: " ++ show key) putStrLn "Your encrypted message is:" putStrLn (encryptString key message) putStrLn "Your decrypted ciphertext is:" putStrLn (decryptString key (encryptString key message))