38

How do random number generator works? (for example in C/C++ Java)

How can I write my own random number generator? (for example in C/C++ Java)

Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
Rella
  • 65,003
  • 109
  • 363
  • 636
  • possible duplicates : http://stackoverflow.com/questions/1359318/how-does-random-actually-work, http://stackoverflow.com/questions/6593636/how-does-software-generate-random-numbers-and-how-do-these-compare-with-human-g – Nikana Reklawyks Nov 01 '12 at 20:00
  • 2
    Donald Knuth discusses random number generation in the first volume of his classic The Art of Computer Programming. I'd start there. Well I did start there, very long ago. :) – Cheers and hth. - Alf Jul 21 '15 at 11:33

9 Answers9

20

There is also this algorithm:

enter image description here

Oh, and more seriously:

Random number generators use mathematical formulas that transfer set of numbers to another one. If, for example, you take a constant number N and another number n_0, and then take the value of n mod N (the modulo operator), you will get a new number n_1, which looks as it if is unrelated to n_0. Now, repeat the same process with n_1 and you'll get another number. What you have here is a (VERY BAD) generator of seemingly random numbers.

Remember, the method I've described here is a toy method that should not be used for anything serious. It does, however, illustrate the general principle.

Also note:

If all scientific papers whose results are in doubt because of bad rands were to disappear from library shelves, there would be a gap on each shelf about as big as your fist.

(paraphrased from chapter 7 of Numerical recipes). This is a must-read text for anyone who uses random number generators for any serious work.

Boris Gorelik
  • 29,945
  • 39
  • 128
  • 170
  • 11
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Eelke Apr 18 '15 at 10:03
  • Eelke: Is it better now? – Boris Gorelik Apr 19 '15 at 12:01
  • 1
    The problem with randomness is that you can never be sure—but you can pass the generated numbers through a statistical test (I remember the chi-square test from my college days) and get a percentage called "degree of confidence". But you'll possibly need more than six consecutive nines to get a negative result :) – Álvaro González Jul 11 '16 at 09:35
18

One of the things to keep in mind is that there are no 'true' random number generators. They just generate numbers that look random to us mere mortals.

One of the easiest examples of this (to implement, as well) is the Linear congruential generator. Sure, the numbers look unpredictable to you and me, but they're actually evenly spaced within a finite field.

Of course, some generators, like Blum Blum Shub aren't predictable for an outsider even if he applies serious mathematical skills and computing power to the task, but at the fundamental level, random number generators aren't random; they're regular and predictable.

Michiel Buddingh
  • 5,783
  • 1
  • 21
  • 32
  • 2
    \dev\random is more random, and you can also attach something to measure things like exact air temp or a geiger counter for more randomness. – James Black Nov 11 '09 at 16:44
  • 2
    LCGs do not necessarily produce output in *any* finite field, never mind evenly spaced numbers. – Dietrich Epp Oct 14 '12 at 18:38
  • Thank you for the links, I'll drop in another one: https://en.wikipedia.org/wiki/Hardware_random_number_generator What I mean is, there actually are true RNGs. But they are quite uncommon nowadays. – gluk47 Apr 27 '16 at 11:13
  • I have finally found someone who agrees that computers cannot really pick random numbers. I like to think about it like this: computers do not do anything themselves. In fact, it is arguable they are the stupidest things in the universe. Everything done by computers is programmed by humans. Because we have an intellect, we can pick seemingly random numbers, but that's not true for computers. –  Jul 25 '16 at 19:16
4

How I made them in the old days was by getting some value from the system that changes really rapidly, for example the system millisecond timer.

The next thing you have to do is to apply some formula that will generate a new number from this "input" number and clip it to the range you need, eg 0..255:

random_number = integer(formula(timer-value)) MOD 255

That way, you have a new "random" number every time you call the function.

An example formula function could be:
formula(x) = ((x XOR constant) + constant2) MOD range
XOR used to be one of my favourites.


Update: I realize that this formula is a very bad one, it generates a pretty predictable set of numbers. Also, the system timer is too predictable as a source. So for most applications, this does not suffice. If you need better randomness, use more sources than just the system timer and better formulas to combine them.

littlegreen
  • 7,290
  • 9
  • 45
  • 51
  • 5
    A millisecond timer is not a fast changing system, for most computational purposes it is a semi-fixed number, changing once in a while. And when it does change, it changes in a completely predictable terms. In best case the time should be used as a seed, and only once in a while to make sure that the time has changed completely before using it again. So better than a timer is a system that changes *really* rapidly, and non predictive. – daramarak Nov 11 '09 at 17:26
  • Good comment. Tried to mention this disclaimer under "Update". – littlegreen Jul 25 '15 at 17:00
2

I found this one for Java:

http://www.javamex.com/tutorials/random_numbers/java_util_random_algorithm.shtml

by googling how random functions work java

I'm sure the answer is language-specific, but you can try altering my Google query for the language of your choice.

David
  • 72,686
  • 18
  • 132
  • 173
1

There is a lot of information available about how they are working ... see Konamiman's answer and use google a bit.

Why would you like to write a new random generator? You probably should not try to do so ... until you need something very special. For example in a game you could use a shuffle bag which produces 'fair' random values - have a look at this interesting question on SO.
I post this here, because I really liked the idea and implementation when I read about it the first time :)

Community
  • 1
  • 1
tanascius
  • 53,078
  • 22
  • 114
  • 136
1

It's also common to seed these types of generators by using something like the fifth decimal of the current clock time which also appears random to us. Add together inputs from a few chaotic systems, e.g. weather data, stock market data, again, using modulus and you have good seed numbers.

user3918295
  • 335
  • 2
  • 7
1

https://github.com/fsssosei/Pure_PRNG/tree/main/src/prng_algorithms_package Here is the implementation of the following algorithm: Inversive Congruential Generator, LCG64_32_ext, XSM64, Ran64

sosei
  • 21
  • 2
0

here is some code for rolling dice it uses a random number generator I developed myself the pad in this RNG hold hexadecimal values 15 of them in all

 DIM pad(15) AS INTEGER
CLS
egg$ = "EFCDBA01457FA968"
  ghh$ = egg$
 nom% = 0
zen% = LEN(ghh$)
WHILE zen% > 0
opp$ = LEFT$(ghh$, 1)
eff% = ASC(opp$)
IF eff% >= 48 AND eff% <= 57 THEN eff% = eff% - 48 ELSE eff% = (eff% - 65) + 10
IF eff% > 15 THEN eff% = eff% - 32
pad(nom%) = eff%
nom% = nom% + 1
zen% = LEN(ghh$) - 1
ypp$ = RIGHT$(ghh$, zen%)
ghh$ = ypp$
WEND
sol& = 0
FOR zyx% = 0 TO 3
sol& = sol& * 16
sol& = sol& + pad(zyx%)
NEXT zyx%
sat% = sol& - 32768
RANDOMIZE sat%
FOR zyx% = 0 TO 15
PRINT HEX$(pad(zyx%));
NEXT zyx%
RANDOMIZE TIMER
respawn:
INPUT "sides per die"; die%
INPUT " number of dice"; dice%
INPUT "number to add to dice roll can be negative"; num%
INPUT "multiplier use 1 if so desired single precision floating point number"; g!
PRINT " hit any key to roll again with these values hit n for new values and q to quit"
PRINT " the number will be added or subtracted first before the multiplier takes effect"
reroll:
sum! = 0
FOR x% = 1 TO dice%
GOSUB rndmz
GOSUB demf
GOSUB drand
k% = INT(dr# * die%) + 1
sum! = sum! + k%
NEXT x%
sum! = (sum! + num) * g!
PRINT "you rolled a :"; sum!
i$ = ""
WHILE i$ = "": i$ = INKEY$: WEND
IF i$ = "n" THEN GOTO respawn
IF i$ = "q" THEN GOTO theend
GOTO reroll
theend:
SYSTEM
END
rndmz: rhet$ = ""
zum% = 0
FOR yxz% = 0 TO 15
FOR zyx% = 0 TO 15
IF zyx% MOD 3 = 0 THEN zum% = (zum% + pad(zyx%)) MOD 16
IF zyx% MOD 3 = 1 THEN zum% = (zum% + 16 - pad(zyx%)) MOD 16
IF zyx% MOD 3 = 2 THEN zum% = (zum% + INT(RND * 16)) MOD 16
NEXT zyx%
rhet$ = rhet$ + HEX$(zum%)
NEXT yxz%
ghh$ = rhet$
RETURN
demf: nom% = 0
zen% = LEN(ghh$)
WHILE zen% > 0
opp$ = LEFT$(ghh$, 1)
eff% = ASC(opp$)
IF eff% >= 48 AND eff% <= 57 THEN eff% = eff% - 48 ELSE eff% = (eff% - 65) + 10
IF eff% > 15 THEN eff% = eff% - 32
pad(nom%) = eff%
nom% = nom% + 1
zen% = LEN(ghh$) - 1
ypp$ = RIGHT$(ghh$, zen%)
ghh$ = ypp$
WEND
FOR zyx% = 0 TO 15
'PRINT HEX$(pad(zyx%));
NEXT zyx%
RETURN
drand: dr# = pad(0)
FOR eff% = 1 TO 15
dr# = dr# / 16
dr# = dr# + pad(eff%)
NEXT eff%
dr# = dr# / 16
RETURN
derf: a# = 1
x# = 1
b# = 1 / (2 ^ .5)
c# = .2500000000000011#
FOR u% = 1 TO 3
y# = a#
a# = (a# + b#) / 2
b# = (b# * y#) ^ .5
c# = c# - x# * (a# - y#) ^ 2
x# = 2 * x#
pi# = ((a# + b#) ^ 2) / (4 * c#)
PRINT pi#
NEXT u%
pi# = pi# + .000000000000015#
PRINT pi#

this here at the end calculates pi to almost as many places possible in just 3 loops through the algorythm sorry about it being written in archaic basic language, it's the only programing language I know, it might be possible to port this over to c++ or Java
Just take a careful look at the logic of this and especially close attention to the priming or seeding / initialization procedures, which must be used or it will fail as a good rng... this is one I developed for gaming purposes where having huge security is not as much of a concern as speed...

John Einem
  • 51
  • 3
-1

Depends on the goal: speed vs quality vs security.

Speed & Security: Linear Congruence is straight forward and does not depend on a public source, privacy of a key is crucial for crypto systems.

Quality: random.org is a source of true random, where you get about 10000 16-Bit values per day free.

Combining several random sources (simpliest XOR) combines their properties.

So, if you also maintain a pool of true random numbers, you have all of speed, quality and security.

Sam Ginrich
  • 661
  • 6
  • 7