1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ Commented May 18, 2014 at 2:03
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Anonymous
    Commented May 18, 2014 at 2:12
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented May 18, 2014 at 2:31

1 Answer 1

2
\$\begingroup\$

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 -)

\$\endgroup\$
2
  • \$\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 the map? \$\endgroup\$ Commented May 18, 2014 at 2:00
  • \$\begingroup\$ 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. \$\endgroup\$
    – Anonymous
    Commented May 18, 2014 at 2:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.