wordpass 1.0.0.9 → 1.0.0.10
raw patch · 5 files changed
+62/−14 lines, 5 filesdep ~basedep ~optparse-applicativedep ~unix-compat
Dependency ranges changed: base, optparse-applicative, unix-compat
Files
- Text/WordPass.hs +49/−5
- WordPass.hs +1/−0
- changelog +4/−0
- stack.yaml +1/−1
- wordpass.cabal +7/−8
Text/WordPass.hs view
@@ -3,7 +3,7 @@ -- | Main module generating passwords. module Text.WordPass where -import Data.Ratio+import Data.Monoid((<>)) import System.IO (hFlush, stdout) import System.Directory hiding (isSymbolicLink) import System.FilePath ((</>), takeDirectory)@@ -12,7 +12,7 @@ import Data.Text(Text) import qualified Data.Set as Set import Data.Set (Set)-import Data.Char (isAlpha, isPunctuation, isSymbol)+import Data.Char (isAlpha, isPunctuation, isSymbol, toLower, toUpper) import Test.QuickCheck.Gen import qualified Data.Vector as V import Control.Applicative@@ -89,20 +89,64 @@ -- | Pick a random password, given a words list, and a number of words it will contain. randomPassword :: WordList -> Int -> Gen Text-randomPassword wordlist numWords = do ws <- replicateM numWords $ randomElement wordlist+randomPassword wordlist numWords = do ws <- replicateM numWords $ randomCase $ randomElement wordlist seps <- replicateM numWords randomSeparator return $ Text.concat $ zipWith Text.append ws seps +-- | First character uppercase, all others lowercase+capitalized :: Text -> Text+capitalized word = Text.toUpper first `Text.append` Text.toLower rest+ where+ (first, rest) = Text.splitAt 1 word++-- | First character lowercase, all others uppercase+uncapitalized :: Text -> Text+uncapitalized word = Text.toLower first `Text.append` Text.toUpper rest+ where+ (first, rest) = Text.splitAt 1 word++-- | Swap case for each letter, starting from upper+evenUpperOddLower :: Text -> Text+evenUpperOddLower = Text.pack . go . Text.unpack+ where+ go :: String -> String+ go [] = []+ go [a] = [toLower a]+ go (a:b:cs) = toLower a:toUpper b:go cs++-- | Swap case, starting from lower+evenLowerOddUpper :: Text -> Text+evenLowerOddUpper = Text.pack . go . Text.unpack+ where+ go :: String -> String+ go [] = []+ go [a] = [toUpper a]+ go (a:b:cs) = toUpper a:toLower b:go cs++-- | Randomize letter case within the word.+randomCase :: Gen Text -> Gen Text+randomCase wordGen = do+ word <- wordGen+ changer <- elements caseVariants+ return $ changer word++-- | Different uppercase/lowercase variants of each word.+caseVariants :: [Text -> Text]+caseVariants = [capitalized, uncapitalized,+ Text.toLower, Text.toUpper,+ evenLowerOddUpper, evenUpperOddLower]+ -- | Estimate strength of random password with given inputs. randomPasswordStrength :: V.Vector a -> Int -> Double-randomPasswordStrength wordlist numWords = fromIntegral numWords * logBase 2 wordStrength+randomPasswordStrength wordlist numWords = fromIntegral numWords * (logBase 2 wordStrength) where- wordStrength = fromIntegral $ V.length wordlist * (numSymbols + numNumericSeparators)+ wordStrength = fromIntegral $ V.length wordlist * (numSymbols + numNumericSeparators) * length caseVariants -- | Number of characters within alphabet. numSymbols :: Int numSymbols = V.length symbolChars -- 32 +-- | Since we use two-digit separators, there are 100 different. numNumericSeparators :: Int numNumericSeparators = 100
WordPass.hs view
@@ -3,6 +3,7 @@ -- | Main module generating passwords. module Main where +import Data.Monoid((<>)) import qualified Data.Text.IO as Text import qualified Data.Set as Set import qualified Data.Vector as V
changelog view
@@ -1,4 +1,8 @@ -*-Changelog-*-+1.0.0.10 Jul 2018+ * Random case for words.+ * Bump to GHC 8.4 and LTS 11.2+ 1.0.0.9 May 2018 * Use Test.QuickCheck.Gen for random generation instead of RVar.
stack.yaml view
@@ -15,7 +15,7 @@ # resolver: # name: custom-snapshot # location: "./custom-snapshot.yaml"-resolver: lts-7.8+resolver: lts-11.2 # User packages to be built. # Various formats can be used as shown in the example below.
wordpass.cabal view
@@ -1,5 +1,5 @@ name: wordpass-version: 1.0.0.9+version: 1.0.0.10 synopsis: Dictionary-based password generator description: This script reads dict word lists and generates word-based passwords. Not unlike <http://xkcd.com/936/ xkcd>.@@ -32,13 +32,13 @@ main-is: WordPass.hs other-modules: Text.WordPass other-extensions: OverlappingInstances, MultiParamTypeClasses, FlexibleInstances- build-depends: base >=4.4 && <4.11,+ build-depends: base >=4.4 && <4.12, text >=1.1 && <1.4, containers >=0.5 && <0.6, vector >=0.10 && <0.13, directory >= 1.2 && <1.4,- optparse-applicative >= 0.12 && <0.14,- unix-compat >= 0.4 && <0.5,+ optparse-applicative >= 0.12 && <0.15,+ unix-compat >= 0.4 && <0.6, deepseq >= 1.3 && <1.5, filepath >= 1.3 && <1.5, QuickCheck >= 2.0 && <3.0@@ -49,16 +49,15 @@ library exposed-modules: Text.WordPass other-extensions: OverlappingInstances, MultiParamTypeClasses, FlexibleInstances- build-depends: base >=4.4 && <4.11,+ build-depends: base >=4.4 && <4.12, text >=1.1 && <1.4, containers >=0.5 && <0.6, vector >=0.10 && <0.13, directory >= 1.2 && <1.4,- unix-compat >= 0.4 && <0.5,+ unix-compat >= 0.4 && <0.6, deepseq >= 1.3 && <1.5, QuickCheck >= 2.0 && <3.0,- filepath >= 1.3 && <1.5,- optparse-applicative >= 0.12 && <0.14+ filepath >= 1.3 && <1.5 ghc-options: -O3 -- hs-source-dirs: default-language: Haskell2010