Skip to content

Instantly share code, notes, and snippets.

@mmacphail
Last active December 18, 2017 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmacphail/6042be638357ae44aa5c01a6c6497ff7 to your computer and use it in GitHub Desktop.
Save mmacphail/6042be638357ae44aa5c01a6c6497ff7 to your computer and use it in GitHub Desktop.
Caesar Cipher with Haskell
module Cipher where
import Data.Char
import Data.List (elemIndex)
cChar :: Int -> Char -> Char
cChar shift c = case c `elemIndex` range of
Just index -> if shift < 0
then ((cycle . reverse) range) !! (25 + rShift - index)
else (cycle range) !! (index + shift)
Nothing -> c
where
range = if c `elem` ['a'..'z'] then ['a'..'z'] else ['A'..'Z']
rShift = abs (shift)
cipherChar :: Int -> Char -> Char
cipherChar shift c
| (not . inRange) $ ord c = c
| tShift < start = chr $ tShift + 26
| tShift > end = chr $ tShift - 26
| otherwise = chr $ tShift
where
(start, end) = if c `elem` ['a'..'z'] then (ord 'a', ord 'z') else (ord 'A', ord 'Z')
inRange x = x `elem` [start..end]
rShift = shift `mod` 26
tShift = (ord c) + rShift
unCipherChar :: Int -> Char -> Char
unCipherChar shift = cipherChar (-shift)
caesar :: Int -> String -> String
caesar shift = map (cipherChar shift)
unCaesar :: Int -> String -> String
unCaesar shift = map (unCipherChar shift)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment