-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeek4_Code__cipher.hs
More file actions
50 lines (32 loc) · 1.17 KB
/
Week4_Code__cipher.hs
File metadata and controls
50 lines (32 loc) · 1.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
-- Caesar's Cipher
-- Jeremy.Singer@glasgow.ac.uk
-- great example for QuickCheck
import Data.Char
shouldcipher :: Char -> Bool
-- is this a letter to be ciphered?
shouldcipher c = isLetter(c) && isAscii(c)
cipherchar :: Int -> Char -> Char
-- enciphers single char at a time - NO WRAPPING
cipherchar shift c
| shouldcipher c = chr(ord(c)+shift)
| otherwise = c
-- encipher a whole string
cipher :: Int -> [Char] -> [Char]
cipher shift plaintext = map (bettercipherchar shift) plaintext
decipher :: Int -> [Char] -> [Char]
-- inverse of cipher function
decipher shift ciphertext = cipher (-shift) ciphertext
wraparound shift c
-- should we wrap around the alphabet, if we shift past Z?
| isLower(c) && ord(c)+shift > ord 'z' = True
| isUpper(c) && ord(c)+shift > ord 'Z' = True
| otherwise = False
bettercipherchar :: Int -> Char -> Char
-- implementation of character substitution with wrapping
bettercipherchar shift c
| shouldcipher c = chr(ord(c) + adjustedshift)
| otherwise = c
where adjustedshift = let shift' = shift `mod` 26
in if (wraparound shift' c)
then shift'-26
else shift'