Random.org Library

RandomOrg Library

If you don’t know what Random.org is, check it out. It uses atmospheric noise to generate randomness, which will end up being much more “truly” random than pseudo-random generators (like math.random). So if you need some better randomness, this is a good library to use. Of course, it has to make an HTTP call and thus is much slower than calling math.random, but perhaps useful for generating seeds and such.

I spent a couple hours today writing a library to interface with Random.org’s API. It was pretty straight-forward since their documentation was well-detailed.

To use this library, you have to register for a beta key, which they will just email to you. Then you pass that key to the library’s Init function.

Here’s some quick examples:

local randomOrg = require(game.Whatever.RandomOrg)
randomOrg.Init("YourApiKeyHere")
--
local diceRoll = randomOrg.Integer(1, 6)
print(diceRoll)
--
local manyDiceRoll = randomOrg.Integer(1, 6, 10) -- 10 rolls
for i = 1,#manyDiceRoll do
   print("Roll " .. i .. ": " .. manyDiceRoll[i])
end
--
local uuid = randomOrg.UUID()
print(uuid)
--
local chance = randomOrg.Decimal()
if chance > 0.5 then ... end
--
local str = randomOrg.String(10, "abcdefg1234567")
print(str)
--
local usage = randomOrg.GetUsage()
for key,value in pairs(usage) do
   print(key, value)
end

Here’s a list of all the methods:

Random.Init(apiKey)
Random.GetUsage()

Random.Integer(min, max [, count])
Random.Decimal([count])
Random.Gaussian(mean, standardDeviation, significantDigits [, count])
Random.String(length, characters [, count])
Random.UUID([count])
Random.Blob(size [, format, count])

Note: If “count” is provided and is not 1, then the result is instead a table with the results.

The “format” for Blob can either be “base64” or “hex” and defaults to base64 if not provided.

The minimum/maximum/ranges/etc. for the parameters can be found within the ModuleScript source itself, or on the API web page I linked in the first paragraph.

Disclaimer:
This is slow! It in no way is trying to compete with the speed of math.random at all. Every function call has to make an HTTP call. There are limits on your API key, which can be watched using the GetUsage function. I made this more as a fun little project, but I hope someone is able to use it somehow practically.

2 Likes

Maybe it is an idea that you keep a backlog of 0-1 fractions that can be returned instantly (and used to compute the other methods) and to send requests asynchronously when the backlog gets too short?

For example always keep 100 numbers in there, and when it gets below 100 make your code send a request for another 100 asynchronously.

That could work. Also note that there is a “count” parameter, so you can actually request a table of thousands of random numbers at once if you wanted to.

randomOrg.Decimal(10000) -- 10,000 random decimal numbers in a table

True, I guess it can be programmed on top of this library.

1 Like

Please add a disclaimer that there are limits to how many request can be made, and things might change once it goes out of beta.

So I would:

  1. Provide a fallback if you havent already (so a game wont break if this fails), with a warning when its used (I would also force the user to explicitly state whether they want it enabled or disabled, its not nice if they get not-really-random numbers if they really do need truly random ones - I doubt anyone on roblox cares but its still more ‘secure’)
  2. Ensure the random numbers are retrived efficiently (can you retrieve a large pool of random bits at once, instead of many small requests?). This would also remove the HTTP latency for most calls.

Sadly, the library is probably more practical than trying to implement a decent PRNG in Lua, as theres no bitwise operators and other things that those algorithms really love to use.

The lack of seed reduces the usefulness of true random numbers for game purposes, though.

Nice, Random.org is really useful. I mentioned their API a few weeks ago actually http://devforum.roblox.com/t/better-results-from-random-numbers/25133/14?u=vaeb

I’ve already mentioned that you can do this. That’s what the ‘count’ parameter is for.

And you can retrieve limits with the GetUsage function.

Surely this would completely negate the issue of the speed (which you mentioned in the disclaimer). You could just send off one HTTP request to gets lots of random numbers and store them all in a table. Then whenever a script needs a random number just return the first value in the table (and then remove it). Also for limits you could just create a function which looks through the table for numbers which are within the limits and returns that number (and removes it from the table of course). For getting fractional (0-1) numbers you could just get the first number in the table and then do something along the lines of:

function intToBaseDec(n)
   return n/10^math.floor(math.log10(n)+1)
end

???

Yeah exactly, so since you can choose how many numbers are returned on each HTTP request there’s no reason to make more than one HTTP request really (so the disclaimer isn’t really an issue).