Page 1 of 3

How to go about daily random numbers

Posted: Sat Jan 08, 2022 4:36 pm
by Gunroar:Cannon()
I want to add a daily and/or weekly level (which is gotten from a random seed) but how would I go about generating this number. I thought it might be straight forward but the numbers might be different on different platforms and how do I get the day? (os.date?)

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 5:15 pm
by grump
One quick idea to generate a "random" number based on the current date:

Code: Select all

local d = os.date('!*t') -- get utc date
local hash = love.data.encode('string', 'hex', love.data.hash('sha1', d.day .. d.month .. d.year))
local rand = tonumber(hash:sub(1, 16), 16)
It's not really random, because you easily generate numbers for any date in advance.

Edit: or like this:

Code: Select all

local d = os.date("!*t") -- get utc date
local seed = d.day * 8271 * d.month * 12837
local rand = love.math.newRandomGenerator(seed, seed + d.year * 9813):random(1, 1000)
Has the same problem though.

I think you'd need a central authority to make this secure.

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 5:47 pm
by Gunroar:Cannon()
grump wrote: Sat Jan 08, 2022 5:15 pm
It's not really random, because you easily generate numbers for any date in advance.

Edit: or like this:

Code: Select all

local d = os.date("!*t") -- get utc date
local seed = d.day * 8271 * d.month * 12837
local rand = love.math.newRandomGenerator(seed, seed * 9813):random(1, 1000)
Has the same problem though.

I think you'd need a central authority to make this secure.
Oh, this looks nice. I guess the fact that it's not *really* random is fine, as long as it's the same on all platforms. I want the maps to be gotten offline so this should suffice.

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 5:57 pm
by grump
The year is was missing in the second one.

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 6:25 pm
by pgimeno
Gunroar:Cannon() wrote: Sat Jan 08, 2022 5:47 pm I guess the fact that it's not *really* random is fine, as long as it's the same on all platforms.
Beware that future versions may change the produced numbers, though. This has happened several times already. So if you port it to a newer version, the maps might not be compatible. The sha1 method does not have this problem, but it's a bit harder to handle, as you don't have functions to yield a range etc.

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 6:50 pm
by grump
And the sha1 method has the flaw that it generates the same number for Jan. 11 and Nov. 1. Leading zeroes would fix this.

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 6:51 pm
by Gunroar:Cannon()
Hmmm... I guess I'll use the first method then. Just thought they might make similar maps :P ... for ... some reason :ehem:

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 6:58 pm
by grump
A secure hash function is a really good PRNG.

Here's the fixed version:

Code: Select all

local d = os.date('!*t') -- get utc date
local hash = love.data.encode('string', 'hex', love.data.hash('sha1', (d.day * 123) .. d.month .. d.year))
local rand = tonumber(hash:sub(1, 16), 16)
(entirely untested!)

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 7:56 pm
by Gunroar:Cannon()
Thanks!

Re: How to go about daily random numbers

Posted: Sat Jan 08, 2022 8:47 pm
by pgimeno
16 hex digits doesn't make much sense, by the way. Doubles can store consecutive integers up to 13 hex digits. It will work if using division to obtain numbers in an appropriate range, but not if using modulo.