module Number.Generate
( generateMax
, generateBetween
, generateOfSize
) where
import Number.Serialize
import Crypto.Random
import qualified Data.ByteString as B
import Data.Bits ((.|.))
generateMax :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)
generateMax rng m = case genBytes (lengthBytes m) rng of
Left err -> Left err
Right (bs, rng') -> Right (os2ip bs `mod` m, rng')
generateBetween :: CryptoRandomGen g => g -> Integer -> Integer -> Either GenError (Integer, g)
generateBetween rng low high = case generateMax rng (high low + 1) of
Left err -> Left err
Right (v, rng') -> Right (low + v, rng')
generateOfSize :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)
generateOfSize rng bits = case genBytes (bits `div` 8) rng of
Left err -> Left err
Right (bs, rng') -> Right (os2ip $ snd $ B.mapAccumL (\acc w -> (0, w .|. acc)) 0xc0 bs, rng')