module System.Random.Atmosphere ( getRandomNumbers -- :: Int -> Int -> Int -> IO (Either String [Int]) , getRandomSequence -- :: Int -> Int -> IO (Either String [Int]) , getRandomStrings -- :: Int -> Int -> Bool -> Bool -> Bool -> Bool -> IO (Either String [String]) , getQuota -- :: IO (Either String Int) ) where import Data.Either import Network.URI import Network.HTTP.Simple -- URI for integer generation int_uri num min max = concat [ "http://random.org/integers/?num=", show num , "&min=", show min , "&max=", show max , "&col=1&base=10&format=plain&rnd=new" ] -- URI for sequence generation seq_uri min max = concat [ "http://www.random.org/sequences/?min=", show min , "&max=", show max , "&format=plain&rnd=new" ] -- URI for string generation str_uri num len digits uppercase lowercase unique = concat [ "http://www.random.org/strings/?num=", show num , "&len=", show len , "&digits=", if digits == True then "on" else "off" , "&upperalpha=", if uppercase == True then "on" else "off" , "&loweralpha=", if lowercase == True then "on" else "off" , "&unique=", if unique == True then "on" else "off" , "&format=plain&rnd=new" ] -- | Used to get a list of random numbers from http://random.org. -- Note: the minimum must be greater than the maximum. The maximum -- amount of numbers you can retrieve is 10,000, and the numbers -- themselves are limited to a range of +/- 1,000,000,000 (inclusive) getRandomNumbers :: Int -- ^ Number of integers to get -> Int -- ^ Minimum number -> Int -- ^ Maximum number -> IO (Either String [Int]) -- ^ Returns either an error string or the list of integers getRandomNumbers num min max | max <= min = return $ Left "err: minimum must be greater than maximum" | num > 10000 = return $ Left "err: can't retrieve more than 10,000 numbers" | abs min > 1000000000 = return $ Left "err: min can't be more/less than 1,000,000,000" | abs max > 1000000000 = return $ Left "err: max can't be more/less than 1,000,000,000" | otherwise = do let uri' = parseURI (int_uri num min max) case uri' of Nothing -> return $ Left "err: parseURI returned Nothing" Just u -> retrieve u (map read . lines) -- | This is just like 'getRandomNumbers', but instead it will -- randomize a given interval of integers. The limits on the minimum/maximum -- are -1e9 to 1e9, inclusive. The interval itself must be less than 10,000. getRandomSequence :: Int -- ^ Minimum -> Int -- ^ Maximum -> IO (Either String [Int]) getRandomSequence min max | max <= min = return $ Left "err: max must be greater than min" | abs max > 1000000000 = return $ Left "err: max can't be greater/less than +/-1e9" | abs min > 1000000000 = return $ Left "err: min can't be greater/less than +/-1e9" | (max - min)+1 > 10000 = return $ Left "err: sequence must be smaller than 10,000" | otherwise = do let uri = parseURI (seq_uri min max) case uri of Nothing -> return $ Left "err: parseURI returned Nothing" Just u -> retrieve u (map read . lines) -- | Generate random strings. NOTE: if you specify to generate unique -- strings, the amount you want to retrieve /must/ be less than or equal to the -- amount of strings that exist within the character set you specify. -- In the future there will be a check for this, but you have to be sure as of -- right now. getRandomStrings :: Int -- ^ Number of strings requested, max is 10,000 -> Int -- ^ Length of each string, max is 20 -> Bool -- ^ Should digits be allowed? -> Bool -- ^ Should uppercase be allowed? -> Bool -- ^ Should lowercase be allowed? -> Bool -- ^ Should each string be unique? -> IO (Either String [String]) getRandomStrings num len digits uppercase lowercase unique | num > 10000 = return $ Left "err: maximum number of strings is 10,000" | len > 20 = return $ Left "err: maximum str len is 20" | otherwise = do let uri = parseURI (str_uri num len digits uppercase lowercase unique) case uri of Nothing -> return $ Left "err: parseURI returned Nothing" Just u' -> retrieve u' lines -- | Used to check how much of your random.org quota you have. Please see -- for more info. getQuota :: IO (Either String Int) getQuota = do let uri = parseURI "http://random.org/quota/?format=plain" case uri of Nothing -> return $ Left "err: parseURI returned Nothing" Just u -> retrieve u read -- helper utility that calls httpGet for us -- it applies some function to the returned string so we can remove some -- boilerplate retrieve uri f = do s <- httpGet uri case s of Nothing -> return $ Left "err: httpGet returned nothing" Just s' -> return $ Right (f s')