-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvigenery.hs
138 lines (115 loc) · 5.1 KB
/
vigenery.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
-- Vigenery. A vigenere cipher program.
-- Author: Brendan Fahy <[email protected]>
--
-- This program allows encryption, decryption, and cryptanalysis of
-- files using the viginere cipher.
--
-----------------------------------------------------------------------
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-----------------------------------------------------------------------
module Main( main ) where
import System
import System.Console.GetOpt
import Data.Maybe( fromMaybe )
import Data.List
import Data.Ord
import Control.Monad
import Numeric
import Char
import Vigenere
main = do
args <- getArgs -- get command arguments
let ( actions, nonOpts, unrec, msgs ) = getOpt' RequireOrder options args
-- error our if incorrect usage
when (0 < length unrec) $ do putStrLn "Unrecognized Options"
print unrec
usage
exitFailure
when (0 < length msgs) $ do putStrLn $ unlines msgs
usage
exitFailure
-- use new options, or defaults if not provided
opts <- foldl (>>=) (return defaultOptions) actions
let Options { optInput = input,
optOutput = output,
optKey = key,
optMode = mode
} = opts
when (mode == Analyize) $ do putStrLn "Analysing"
text <- input
analyze $ take 10000 text
exitWith ExitSuccess
when (key == "") $ do putStrLn "A key is required to encrypt or decrypt"
usage
exitFailure
when (mode == Encrypt) $ do putStr ("Using " ++key ++ " encrypting ")
text <- input
output $ encrypt text key
when (mode == Decrypt) $ do putStrLn ("Decrypting file with" ++ key)
text <- input
output $ decrypt text key
exitWith ExitSuccess
analyze xs = do putStrLn "Best Kasiski guesses"
print $ take 15 lengths -- show the 15 best guesses
putStrLn "Indicies Of Coincidence"
print $ map (\x -> showFFloat (Just 4) x "") ics
putStrLn "The keyword!"
print thekey
where lengths = filter (>1) $ kasiski xs
guess = mode $ take 15 lengths
thekey = findkey guess xs
ics = indiciesOfCoincidence guess xs
mode = head . maximumBy (comparing length) . group . sort
data Mode = Encrypt | Decrypt | Analyize deriving (Eq)
data Options = Options {
optInput :: IO String,
optOutput :: String -> IO (),
optKey :: String,
optMode :: Mode
}
defaultOptions :: Options
defaultOptions = Options {
optInput = do putStrLn "Need input file"
exitFailure,
optOutput = putStrLn,
optKey = "",
optMode = Encrypt
}
options :: [OptDescr (Options -> IO Options)]
options = [
Option ['V'] ["version"] (NoArg showVersion) "show version number",
Option ['i'] ["input"] (ReqArg readInput "FILE") "plaintext file to read",
Option ['o'] ["output"] (ReqArg writeOutput "FILE") "output file to write" ,
Option ['k'] ["key"] (ReqArg getKey "KEYWORD") "output file to write",
Option ['e'] ["encrypt"] (NoArg (setMode Encrypt)) "encrypt plain text",
Option ['d'] ["decrypt"] (NoArg (setMode Decrypt)) "decrypt cipher text",
Option ['a'] ["analysis"] (NoArg (setMode Analyize)) "Run cryptanalysis"
]
usage = do
putStrLn "Usage : vigenery [-mode] [-i input] [-k key]"
putStrLn "Encryption"
putStrLn " vigenery -e -i inputfile.txt -k key"
putStrLn " vigenery -e -i inputfile.txt -k key -o output.txt"
putStrLn "Decryption"
putStrLn " vigenery -d -i inputfile.txt -k key"
putStrLn " vigenery -d -i inputfile.txt -k key -o output.txt"
putStrLn "cryptAnalysis"
putStrLn " vigenery -a -i inputfile.txt"
showVersion _ = do
putStrLn "Version 0.8"
exitWith ExitSuccess
readInput arg opt = return opt { optInput = myread arg }
writeOutput arg opt = return opt { optOutput = writeFile arg }
getKey arg opt = return opt { optKey = show arg}
setMode arg opt = return opt { optMode = arg }
myread arg = do putStrLn $ "file " ++ arg
readFile arg