48 lines
1.3 KiB
Haskell
Executable File
48 lines
1.3 KiB
Haskell
Executable File
import Data.Char
|
|
|
|
lowers :: String -> Int
|
|
lowers xs = length [x | x <- xs, x >= 'a' && x <= 'z']
|
|
|
|
count :: Char -> String ->Int
|
|
count x xs = length [x' | x' <- xs, x==x']
|
|
|
|
positions :: Eq a => a -> [a] -> [Int]
|
|
positions x xs = [i | (x',i) <- zip xs [0..n], x == x']
|
|
where n = length xs - 1
|
|
|
|
let2int :: Char -> Int
|
|
let2int c = ord c - ord 'a' --caracteres a unicode
|
|
|
|
int2let :: Int -> Char
|
|
int2let n = chr (ord 'a' + n)
|
|
|
|
shift :: Int -> Char -> Char
|
|
shift n c | isLower c = int2let ((let2int c + n) `mod` 26)
|
|
| otherwise = c
|
|
|
|
cifrar :: Int -> String -> String
|
|
cifrar n xs = [shift n x | x <- xs]
|
|
|
|
table :: [Float]
|
|
table = [11.72,1.49, 3.87, 4.67,13.72,0.69,1.00,1.18,5.28,0.52,0.11,5.24,3.08,6.83,8.44,2.89,1.11,6.41,7.20,4.60,4.55,1.05,0.04,0.14,1.09,0.47]
|
|
|
|
porciento :: Int -> Int -> Float --fromIntegral :: Int a Float
|
|
porciento n m = (fromIntegral n / fromIntegral m) * 100
|
|
|
|
frec :: String -> [Float]
|
|
frec xs = [porciento (count x xs) n | x <- ['a'..'z']]
|
|
where n = lowers 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 :: String -> String
|
|
crack xs = cifrar (-factor) xs
|
|
where
|
|
factor = head (positions (minimum chitab) chitab)
|
|
chitab = [chisqr (rotate n table') table | n <- [0..25]]
|
|
table' = frec xs
|