Need 100% random... :D

For everything that's not in any way related to PureBasic. General chat etc...
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

That was interesting and some new knowledge for me, Nik. Thanks.
@}--`--,-- A rose by any other name ..
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

I can't speak for all Linuxes, but I know for sure that RedHat 6.x used a random number generator which was based on a seed.
Nik
Addict
Addict
Posts: 1017
Joined: Fri May 13, 2005 11:45 pm
Location: Germany
Contact:

Post by Nik »

It's probably distribution idependent since it is a Kernel thing, but yeah it uses a seed this helps to peoduce more values out of one which has good randomness, the thing is not wether a algorithm uses a seed but where the value for the seed comes from, and Linux uses hardware noiso to generate it, it would also be good to get new seeds when new noise randomness is available, but I don't know more about it.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

In RedHat, the seed was even saved on power-off and restored on power-on. (I don't know why.)
theNerd
Enthusiast
Enthusiast
Posts: 131
Joined: Sun Mar 20, 2005 11:43 pm

Post by theNerd »

It is very difficult to create truly random numbers. Many large computers that develop products that require true random values need external devices that create the seed and/or random number (ex. First Data uses very expensive external devices for their credit card manufacturing.) Some of these devices use light waves to create the random value.
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

It's actually not very difficult to produce truly random numbers as I've previously mentioned, and it's not that expensive either (think about the cost of a diode). I think this has been a good discusion, and one that highlights the weakness of using the clock as a seed.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Just remember, there is two kinds of random number generators.

The cryptologically "secure" one.
The goal here is to make sure that numbers do not repeat,
and if they do it should only happen after all other numbers has been exhausted.

Then there is the "random" one,
Kind of a misnomer really as this (and the previous) are both pseudo-random.
The goal with this one is to make sure that there is a even spread,
optimally all numbers in the range should occur with the exact same frequency.
i.e. If you got the range 0-1 then 50% of numbers should be 0 and 50% of numbers should be 1.

It is extreemly difficult to avoid bias in both those types of generators.

The first is used mostly for encryption and similar,
the second is most popular with games and so on.

Simpler random generators sorta do not attempt either of the two methods. (Like PureBasic's generator I guess)
These are more of the traditional kind, either manualy seeded or automaticaly seeded, uses simple seeding values like time or similar.
(seconds from 1 1 1970 midnight GMT is suspectible to same instance issues if two programs (or threads) start within the same second though).

For most people it's usually enough, it is not adviced for serious cryptography though, nor for a perfect spread of numbers (fo AI and scientific research), i.e it can't generate "noise" numbers.

My suggestion is to keep PB's random generator as it is,
if people wish to modify the behaviour they can by re-seeding it using some more unique value than system time, thats why the seed function exist after all.

But I'd like to suggest (maybe this belongs in the feature request forum though),
is that PB later gets two "more" RND generators.
So that eventually PB will have 3 random number generators.

The traditional one:
Random() and RandomSeed()

Cryptologicaly secure:
RandomSecure() and RandomSecureSeed()

Even spread:
RandomSpread() and RandomSpreadSeed()

Yeah yeah silly names I know, it's just an example.
The cryptologic variant may fit better in the cipher lib.
The traditional (current) one is fine where it is.
The even spread on Im' unsure of where it belongs,
it's sorta game and math oriented really.
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

Rescator, thanks for that. The idea of another 2 random number generators is interesting.. would this mean another pair of algorithms is required, or using a 'quality' seed (non-biased, for the case of games) is sufficient?
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

You know, PB's generator is pretty darn good actualy for games and stuff.
What might be needed in addition is a cryptologicaly "secure" variant
(and add it to the chiper lib).


Run this test:

Code: Select all

DisableDebugger

numbers.l=1000000

zero.l=0
one.l=0
n.l=0
i.l=0

;RandomSeed(Date()) ;optional as PB allready do this at program start,
;but this is how/where you would restore/set the seed from a saved game or similar.

start=ElapsedMilliseconds() 
For i=1 To numbers
 n=Random(1)
 If n=1
  one+1
 Else
  zero+1
 EndIf
Next
stop=ElapsedMilliseconds()

spread.d=one/zero

text$=Str(zero)+" zeros"+#LF$
text$+Str(one)+" ones"+#LF$

percent.d=0.0
If spread>1.0
 percent=100.0/spread
Else
 percent=spread*100.0
EndIf

text$+StrD(percent)+" percent uniform spread"+#LF$

speed.d=(stop-start)/1000.0
text$+StrD(speed)+" seconds to generate "+Str(numbers)+" numbers"+#LF$

MessageRequester("Random() Test",text$)
If the spread is 100% that means it is perfectly uniform,
which is pretty much impossible to do without actualy keeping track
of all previous values, and no normal generators do that.

If it is anything other than 100% there is a bias,
which is why I show the count of each number so you can see the bias.

This is a standard way (as far as I could learn from info I found)
to test random generators.
Here on the test, 1 million numbers was generated,
if the generator was perfect it would result in 100% meaning
half a million 0's and half a million 1's.

PureBasic (and thus Fred actualy :P ) is very good.
With 1 million numbers generated the spread is over 99%
and the speed is very impressive too btw only fraction of a second.

The higher you set the numbers.l= the longer it takes to run the test obviously, 1 billion took over half a minute here,
but the spread weas even closer to 100%.
If you reduce the numbers.l= to something very low, you will find that the spread gets worse.
numbers.l=10 for example, you may actualy end up wih 0% spread
(only 0's for example), or anywhere between 0-100%.

So the more numbers/runs the the better spread you get.
Which is good, esp for a game that may need several thousand if not millions of random numbers during a game session for events etc.

A word of warning though (altough you can try).
Do not use RandomSeed(Date()) or similar right inside the loop.
You will find horrible spread of numbers.

My recommendation? Don't use RandomSeed() in the loop unless you really know what you are doing.

It would be nice with a GetRandomSeed() though as a game could then "save" the seed and then set it later (when a save game is loaded)
to ensure that the random state is consistent across save games.

Hmm. GetRandomSeed() and rename RandomSeed() to SetRandomSeed() so it matches the naming conventions of other stuff?

Anyway, Random() impress me, I wasn't aware it was as good as this.

EDIT:
For info on cryptographicaly secure random genrators here is a nice link,
http://www.ssh.fi/support/cryptography/algorithms/
http://www.itl.nist.gov/fipspubs/fip186.htm (no idea what license these algorythms has though)
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

Rescator, thank you very much for posting this.. it's very interesting. I think chi-squared test is another good check for random number testing (analysis of expected outcomes).
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Post by nco2k »

@Rescator
i agree for GetRandomSeed() / SetRandomSeed() and the secure random, but im not sure about the even spread random. :?:

by the way, could you please try RandomSeed(720377), and tell me your results?

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

@nco2k
A perfect 100% spread.
And your right, not much need for a even spread random,
current one is damn close and should be more than good enough for most games.

And if Fred added a GetRandomSeed() to fetch the currently used seed,
it would be easier for games that uses random numbers for stuff.
That way you could use one particular seed for AI, another for weather,
another for projectiles another for. well you get it.
Well, you can do that now too, but a GetRandomSeed() would be nice for us lazy people, and esp. since there is no way to get the seed that a PB program starts with currently.

@mskuma
Hehe, I find stuff like this facinating myself :)
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Actually you can do RandomSeed(ElapsedMillisecond()) which will do exactly the same than calling the Random() without specifying any seed.
Post Reply