56 lines
1.6 KiB
Haskell
56 lines
1.6 KiB
Haskell
{-# LANGUAGE RecordWildCards #-}
|
|
|
|
import System.IO
|
|
import System.Console.ArgParser
|
|
import Control.Monad
|
|
import Control.Applicative
|
|
|
|
import Paths_alea (getDataFileName)
|
|
import Alea.Diceware
|
|
import Alea.Random
|
|
|
|
data ProgArgs = ProgArgs
|
|
{ interactive :: Bool
|
|
, dictionary :: FilePath
|
|
, phraseLength :: Int
|
|
, phrases :: Int
|
|
} deriving (Show)
|
|
|
|
parser :: IO (ParserSpec ProgArgs)
|
|
parser = (\path -> ProgArgs
|
|
`parsedBy` boolFlag "interactive" `Descr` "Manually insert numbers"
|
|
`andBy` optFlag path "dictionary" `Descr` "Specify dictionary file path"
|
|
`andBy` optFlag 6 "lenght" `Descr` "Number of words in a passphrase"
|
|
`andBy` optFlag 1 "phrases" `Descr` "Number of passphrases to generate")
|
|
<$> path
|
|
|
|
interface :: IO (CmdLnInterface ProgArgs)
|
|
interface =
|
|
(`setAppDescr` "A diceware passphrase generator") <$>
|
|
(`setAppEpilog` "Alea iacta est.") <$>
|
|
(mkApp =<< parser)
|
|
|
|
main :: IO ()
|
|
main = interface >>= flip runApp (readDict >=> exec)
|
|
|
|
-- Default path of the dictionary
|
|
path :: IO FilePath
|
|
path = getDataFileName "dict/diceware"
|
|
|
|
-- Read dictionary file
|
|
readDict :: ProgArgs -> IO ProgArgs
|
|
readDict args@ProgArgs{..} =
|
|
(\x -> args {dictionary = x}) <$> readFile dictionary
|
|
|
|
-- Main function
|
|
exec :: ProgArgs -> IO ()
|
|
exec args@ProgArgs{..} =
|
|
if interactive
|
|
then interact (unlines . map dice . lines)
|
|
else do
|
|
randWords dictSize phraseLength >>= putStrLn . unwords . map dice'
|
|
when (phrases > 1) $ exec args {phrases = phrases - 1}
|
|
where
|
|
(dict, dictSize) = (parseDiceware dictionary, length dict)
|
|
dice n = readDiceware dict (read n :: Int)
|
|
dice' n = readDiceware' dict n |