Page 1 of 1

Determine what the random seed was?

Posted: Fri May 14, 2010 11:56 am
by SFSxOI
When the PureBasic Random() is used it generates its own random seed, is there a way to determine what the seed was?

Re: Determine what the random seed was?

Posted: Fri May 14, 2010 11:57 am
by Fred
Nop. You can use RandomSeeed() to fix your own randomseed and have predictable random results.

Re: Determine what the random seed was?

Posted: Fri May 14, 2010 12:32 pm
by SFSxOI
Thats what I thought. RandomSeed() is not a consideration for me as i do not want to set a seed. Thanks Fred

Re: Determine what the random seed was?

Posted: Fri May 14, 2010 7:28 pm
by Rescator
Hmm! Hey Fred, what about enhancing RandomSeed() then?

Example:
Result=RandomSeed([Value])
Description

Changes the actual random number seed for the values returned with Random().
If no Value is given then PureBasic will generate a new seed using it's internal method
Result is the seed that was created or set.

Note: each time a program is started, a new seed is generated, therefore RandomSeed() is useful only when the goal is to generate the same random numbers in the same order every time the program is executed.
Then again this may be too much of a change for the next beta or RC.
So a future version could just add a GetRandomSeed() as well I guess.
Or maybe Result=RandomSeed([Value[,Method]])
Where "Result=RandomSeed()" will return the current seed and,
where "Result=RandomSeed(Value)" will set the seed and return it (kinda redundant but) and,
where "Result=RandomSeed(Value,1)" will set the seed using the builtin method and return it (the Value is just ignored in this case).

Sorry, just ignore me if you like, I'm just brainstorming here, as adding yet another command could be avoided,
the issue though is how to make sure RandomSeed() remains backwards compatible (as far as possible).

@SFSxOI I guess you need to store the seed and restore it to repeat the sequence at a later time? (like in a game's savefile etc. or a simulation?)
I don't recall what the native method is, but I think that it's close to RandomSeed(ElapsedMilliseconds()),
so you could just store ElapsedMilliseconds() and use that and set the seed.

Sure, that RandomSeed() code that PureBasic does on startup is then wasted, which irks me a little as well :P


Ooh! Hey Fred, what about adding a constant instead? Like #PB_CurrentRandomSeed or #PB_StartupRandomSeed ?
Or would that just be confusing for people?

Re: Determine what the random seed was?

Posted: Fri May 14, 2010 9:25 pm
by Little John
Sorry, I can't see a need for these suggested additional functions.
If you want to keep the seed under control, use RandomSeed(seed).
If you don't want to choose the value for seed yourself, use Random() for this purpose:

Code: Select all

#Max = 2147483647
seed = Random(#Max)
Debug seed
RandomSeed(seed)

; Here goes the main code ...
Regards, Little John

Re: Determine what the random seed was?

Posted: Fri May 28, 2010 4:42 pm
by PureLeo
Yeah, if you set the seed yourself, why the need for retrieving it?

*Also you could use RandomSeed(ElapsedMilliseconds())

Re: Determine what the random seed was?

Posted: Fri May 28, 2010 7:21 pm
by SFSxOI
You don't always set the seed yourself. Random() doesn't let you know what the seed was as it just generates a random number, there is no requirement to use RandomSeed() with Random() to generate a random number. I wanted to make sure there WAS NOT a way to retrieve the seed used in Random() for the random number produced.

Re: Determine what the random seed was?

Posted: Sat May 29, 2010 11:53 am
by Trond
SFSxOI wrote:I wanted to make sure there WAS NOT a way to retrieve the seed used in Random() for the random number produced.
Oh you should have said that. The seed is a long, which means you can try all possible seeds and see which seed generates the wanted random numbers.

Re: Determine what the random seed was?

Posted: Sun May 30, 2010 8:06 am
by Rescator
Ah! I see!
Well it's probably stored in memory somewhere.

Or if you are wondering about being ab to re-create it externally? Maybe as a PRNG can usually be predicted if you do not reseed now and again.
Sounds to me like you should use the random from the crypt lib instead.
You still have the issue of the seed being stored in memory I think, then again if that is an issue then a hostile program is already running under the same user/elevation level anyway.
You might reduce that risk by running it as admin and just handing the random number to the user level program thus keeping the seed in the running admin exe, on Vista and Win7 if UAC etc is not messed with (turned off etc) that should prevent a user level program from getting the seed from the admin level program.
Don't take my word for it, test it. Most likely the API function to get the process memory will given an access error or similar.

Re: Determine what the random seed was?

Posted: Sun May 30, 2010 3:16 pm
by freak
The internal state buffer of the Random() function is actually much larger than a single long value (this is to prevent short cycles, ie the numbers sequence repeating too soon). RandomSeed() takes a long and applies that in a pattern to the state buffer. The initial seed could easily be changed to take advantage of that and put more data into the state buffer and therefore create sequences that you cannot reproduce with RandomSeed(). At the moment, the initialization just calls RandomSeed() as well though. As the design goal of the Random() function is speed and not security, there is really no need to change that. CryptRandom() is the way to go in this case.
Rescator wrote:You might reduce that risk by running it as admin and just handing the random number to the user level program thus keeping the seed in the running admin exe, on Vista and Win7 if UAC etc is not messed with (turned off etc) that should prevent a user level program from getting the seed from the admin level program.
Don't take my word for it, test it. Most likely the API function to get the process memory will given an access error or similar.
With CryptRandom() there is not state information in the calling process. The generator's internal state as well as the entropy pool for re-seeding are all managed by the kernel. You cannot get to that without root access. However, if an attacker has full access to your program while you generate the numbers then you have lost the battle anyway, as he could just hook the API functions for the random number generation and feed you whatever data he wants. But for most practical applications this scenario only has to be considered by the most paranoid (and even then, just run your program with proper access rights and it is solved) :)