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?
Also, please critique my implementation.
1 Answer 1
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 -)
-
\$\begingroup\$ 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 themap
? \$\endgroup\$Kevin Meredith– Kevin Meredith2014年05月18日 02:00:03 +00:00Commented May 18, 2014 at 2:00 -
\$\begingroup\$ Sorry, I didn't notice the
map
.shift
is OK — yes, you could just writemap (chr . (+ n) . ord)
(as LYaH suggests). It's not necessary to passn
toshift
, because it's in scope. \$\endgroup\$Anonymous– Anonymous2014年05月18日 02:04:14 +00:00Commented May 18, 2014 at 2:04
isAsciiUpper
,isAsciiLower
andmod
. \$\endgroup\$