Learn You a Haskell presents the Caesar Cipher:

The Caesar cipher is a primitive method of encoding messages by shifting each character in them by a fixed number of positions in the alphabet

EDIT

Since I'm not limiting this cipher to letters, it's not actually the Caesarian Cipher. Thanks to Anonymous. This implementation is only a Substitution Cipher.

Here's my implementation:

import Data.Char (ord, chr)

encode :: Int -> String -> String
encode n = map $shift' n where shift' x = chr . (+ x) . ord decode :: Int -> String -> String decode n = map$ shift' n
where shift' x =  chr . abs . ((-) x) . ord


Test:

*Main Data.Char> encode 1 "AAA"
"BBB"
*Main Data.Char>
*Main Data.Char> decode 1 "BBB"
"AAA"


I don't like that I'm using abs in my decode. How can I write a function (through currying) that will subtract X from it?

• Hey 200_Success, thanks for editing to include the proper tag. But, since Anonymous pointed out that it's only a Substitution Cipher, I edited the title and removed the tag. – Kevin Meredith May 18 '14 at 2:03
• I suggest fixing the cipher to actually be Caesarean rather than just documenting the bug. It's a good exercise. Hint: isAsciiUpper, isAsciiLower and mod. – Anonymous May 18 '14 at 2:12
• I've put the tag back, since it's still Caesar-inspired in nature. As the tag description says, caesar-cipher also applies to similar toy-grade ciphers. – 200_success May 18 '14 at 2:31

This is a legitimate substitution cipher, but it's not a Caesarean cipher. A Caesarian cipher affects only letters, and it's modulo the alphabet size: caesar 13 "Hello, world!""Urzzb, jbeyq!"

encode and decode can be the same function (caesar?) called with opposite shifts. (Or with the same shift, when it's 13.)

There's no need for a shift' helper.

How can I write a function (through currying) that will subtract X from it?

(x -)

• thanks for mentioning that I'm not using the actual Caesarian Cipher. When you say that shift' is not needed, you recommend just putting the composed function directly in the map? – Kevin Meredith May 18 '14 at 2:00
• Sorry, I didn't notice the map. shift is OK — yes, you could just write map (chr . (+ n) . ord) (as LYaH suggests). It's not necessary to pass n to shift, because it's in scope. – Anonymous May 18 '14 at 2:04