packages feed

crypto-rng-0.3.0.2: src/Crypto/RNG/Utils.hs

module Crypto.RNG.Utils
  ( randomString
  ) where

import Control.Monad
import Data.Primitive.SmallArray
import GHC.Stack

import Crypto.RNG

-- | Generate random string of specified length that contains allowed chars.
--
-- The list of allowed chars must not be empty.
randomString :: (HasCallStack, CryptoRNG m) => Int -> [Char] -> m String
randomString n allowedList
  | size == 0 = error "List of allowed chars must not be empty"
  | otherwise = map (indexSmallArray allowed)
      <$> replicateM n (randomR (0, size - 1))
  where
    allowed :: SmallArray Char
    allowed = smallArrayFromList allowedList

    size :: Int
    size = sizeofSmallArray allowed