Skip to content

Instantly share code, notes, and snippets.

@svdberg
Created May 29, 2012 12:53
Show Gist options
  • Save svdberg/2828223 to your computer and use it in GitHub Desktop.
Save svdberg/2828223 to your computer and use it in GitHub Desktop.
import Data.List.Split
import qualified Data.Map as Map
import Data.List.HT
buildCipher pw = Map.fromList $ zip [ (x,y) | x <- [0..4], y <- [0..4] ] (concat $ build pw)
where
build = chunk 5 . (`union` delete 'J' ['A'..'Z']) . nub . process --calculate the list of characters in the right order
process = replace "J" "I" . map toUpper . filter isLetter
newDecode k = concatMap (\[x,y] -> code k (-1) x y) . chunk 2
newEncode _ [] = []
newEncode c [x] = newEncode c (x : "X") --always at the end of the message
newEncode c (x:y:xs) | (x==y) = newEncode c [x] ++ newEncode c (y:xs)
| otherwise = code c 1 x y ++ newEncode c xs
code c dir a b
| y1 == y2 = get c (x1 + dir, y1) : [get c (x2 + dir, y2)] --same col
| x1 == x2 = get c (x1, y1 + dir) : [get c (x2, y2 + dir)] --same row
| otherwise = get c (x1, y2) : [get c (x2, y1)]
where
(x1, y1) = findCharInCipher c a
(x2, y2) = findCharInCipher c b
get m (x,y) = m Map.! (mod x 5, mod y 5)
findCharInCipher k c = head . Map.keys $ Map.filter (==c) k
encode m k = (newEncode (buildCipher k) . process) m
decode m k = (newDecode (buildCipher k) . process) m
main = do print $ encode "PROGRAMMING PRAXIS" "PLAYFAIR"
print $ decode "LIVOBLKZEDOELIYWCN" "PLAYFAIR"
@svdberg
Copy link
Author

svdberg commented May 29, 2012

compare this one to the readable version: https://gist.github.com/2794373

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment