Reputation: 139
I'm trying to write a Caesar cipher but with only uppercase alphanumeric. Using ord
or chr
uses the whole ASCII table. How can accomplish this?
This is what I have so far:
alphabet = ['A'..'Z'] ++ ['0'..'9']
c2I = ord c - ord 'A'
i2C = chr (n + ord 'A')
Upvotes: 1
Views: 1339
Reputation: 52290
the basic idea is to use mod
to wrap around to the beginning.
Now it's not efficient (but hey you are using the most unsecure cipher so you might not care to much) but I'll show you using just the alphabet and indexing functions:
import Data.List (elemIndex)
alphabet :: [Char]
alphabet = ['A'..'Z'] ++ ['0'..'9']
ith :: Int -> Char
ith i = alphabet !! j
where j = i `mod` length alphabet
index :: Char -> Int
index c = case c `elemIndex` alphabet of
Just i -> i
Nothing -> error "not inalphabet"
encode :: Int -> String -> String
encode n xs = [ ith $ index x + n | x <- xs ]
this will give you
λ> encode 3 "ABCXYZ012789"
"DEF012345ABC"
now you probably will want to find a way using ord
and chr
- both works if you make a case distinction between A-Z
and 0-9
, because the ranges are:
so you cannot take a one formula without to many tricks
You should try but it's more math from here (you'll probably want something like ord c - ord 'A'
for letters and 26 + ord c - ord '0'
for digits to get it in the range 0-35
first.
Upvotes: 3