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.

asked May 18, 2014 at 1:43
\$\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\$ 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 -)

answered May 18, 2014 at 1:58
\$\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\$ Commented May 18, 2014 at 2:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.