heyyo
heyyo

Reputation: 139

How do I use ORD and CHR with only A to Z and 0 to 9?

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

Answers (1)

Random Dev
Random Dev

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:

  • 65-90 for A-Z
  • 48-57 for 0-9

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

Related Questions