module Crypto.Longshot.Internal
( bruteforce
, bruteforceDeep
)
where
import Control.Applicative
import Control.DeepSeq
import Control.Parallel
import Data.Foldable
import qualified Data.ByteString.Char8 as C
import Language.Haskell.TH
import Crypto.Longshot
import Crypto.Longshot.TH
import Crypto.Longshot.Hasher
$( funcGenerator )
bruteforce :: Int -> String -> String -> Hasher -> Maybe String
bruteforce size chars hex hasher = found
where
found = foldl' (<|>) empty (runPar <%> prefixes)
runPar = bruteforcePar numBind (byteChars chars) (image hex) hasher
numPrefix | size < defNumPrefix = 1
| otherwise = defNumPrefix
numBind = size - numPrefix
prefixes = bytePrefixes numPrefix chars
bruteforcePar
:: Int
-> [C.ByteString]
-> C.ByteString
-> Hasher
-> C.ByteString
-> Maybe String
bruteforcePar n
| n `elem` [0 .. defNumBind] = $( funcList ) !! n
| otherwise = errorWithoutStackTrace "Not available search length"
bruteforceDeep :: Int -> String -> String -> Hasher -> Maybe String
bruteforceDeep size x y z = foldl' (<|>) empty found
where
found = deep x y z <%> [1 .. size]
deep a b c d = bruteforce d a b c
(<%>) :: (NFData a, NFData b) => (a -> b) -> [a] -> [b]
f <%> [] = []
f <%> (x : xs) = y `par` ys `pseq` (y : ys) where
y = force $ f x
ys = f <%> xs