Posts Tagged ‘autokey’

Programming Praxis – Autokey

December 4, 2009

In today’s Programming Praxis we have another cipher algorithm. Let’s get started.

A quick import:

import Data.Char

First of all, we need a function to add and subtract characters.

combine :: (Int -> Int -> Int) -> Char -> Char -> Char
combine f a b = chr $ mod (f (ord a) (ord b) - 2 * 65) 26 + 65

Encrypting or decrypting is just a matter of using this combine function on all the letter pairs of the key and the message.

cipher :: (Int -> Int -> Int) -> String -> String -> String
cipher f key msg = zipWith (combine f) (clean msg) (clean key)
                   where clean = map toUpper . filter isLetter

When encrypting, we can simply append the message to the key.

encrypt :: String -> String -> String
encrypt key msg = cipher (+) (key ++ msg) msg

When decrypting, we instead need to append the unencrypted message, which we do not have yet. Fortunately, thanks to lazy evaluation we can simply recursively call the decrypt function. This means it will produce a stack overflow when fed an empty key, but since that would be useless anyway we don’t really care.

decrypt :: String -> String -> String
decrypt key msg = cipher (-) (key ++ decrypt key msg) msg

All that’s left is to test our functions:

main :: IO ()
main = do print $ encrypt "BONSAI" "Pablo Picasso"
          print $ decrypt "BONSAI" "QOODOXXCBDGD"

That seems to work just fine. Another one down.