-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathex10.hs
85 lines (71 loc) · 1.59 KB
/
ex10.hs
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import Data.Char
positions :: Eq a => a -> [a] -> [Int]
positions x xs = [i | (x', i) <- zip xs [0 ..], x == x']
count :: Char -> String -> Int
count x xs = length [x' | x' <- xs, x == x']
alphabets :: [Char] -> Int
alphabets xs =
length [x | x <- xs, (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')]
let2int :: Char -> Int
let2int c
| isLower c = ord c - ord 'a'
| otherwise = ord c - ord 'A'
int2letLower :: Int -> Char
int2letLower n = chr (ord 'a' + n)
int2letUpper :: Int -> Char
int2letUpper n = chr (ord 'A' + n)
shift :: Int -> Char -> Char
shift n c
| isLower c = int2letLower ((let2int c + n) `mod` 26)
| isUpper c = int2letUpper ((let2int c + n) `mod` 26)
| otherwise = c
encode :: Int -> [Char] -> [Char]
encode n xs = [shift n x | x <- xs]
table :: [Float]
table =
[ 8.1
, 1.5
, 2.8
, 4.2
, 12.7
, 2.2
, 2.0
, 6.1
, 7.0
, 0.2
, 0.8
, 4.0
, 2.4
, 6.7
, 7.5
, 1.9
, 0.1
, 6.0
, 6.3
, 9.0
, 2.8
, 1.0
, 2.4
, 0.2
, 2.0
, 0.1
]
percent :: Int -> Int -> Float
percent n m = (fromIntegral n / fromIntegral m) * 100
freqs :: String -> [Float]
freqs xs =
[ percent ((count l xs) + (count u xs)) n
| (l, u) <- zip ['a' .. 'z'] ['A' .. 'Z']
]
where
n = alphabets xs
chisqr :: [Float] -> [Float] -> Float
chisqr os es = sum [((o - e) ^ 2) / e | (o, e) <- zip os es]
rotate :: Int -> [a] -> [a]
rotate n xs = drop n xs ++ take n xs
crack :: [Char] -> [Char]
crack xs = encode (-factor) xs
where
factor = head (positions (minimum chitab) chitab)
chitab = [chisqr (rotate n table') table | n <- [0 .. 25]]
table' = freqs xs