Click here to Skip to main content
15,891,184 members
Articles / Programming Languages / ASP
Article

PRNG (Pseudo Random Number Generator)

Rate me:
Please Sign up or sign in to vote.
1.75/5 (9 votes)
12 Jun 20015 min read 160.3K   1.3K   13   27
An ActiveX control for creating random numbers in VB/VBScript/ASP pages

Introduction

If you have tried to use Randomize and Rnd in your programs, you know what I mean. The odds are incredible, but still you are facing those same reappearing "random" numbers.

This is because languages like VB and several others have a built-in "random number table". VB's, and hence VBScript's, is a table consisting of 16,777,215 random numbers (this is, coincidentally, one of those magic numbers). Calling randomize() places you at some spot in the table (this is typically based on time of day). Calling rnd() returns that value and steps you to the next value in the list. If you run the program again without calling randomize, rnd() will give you the same value every time.

The Problem: Getting Good random numbers

Personally, I just got too tried of having to deal with the issues appearing from the use of Randomize and Rnd in my VB and my ASP applications and since necessity is the mother of all inventions, I created my own PRNG (Pseudo Random Number Generator).

The best Random Number Generators are hardware based. Since I am a software guy, I went for "an algorithm that mimics the generation of random numbers" or in other words a Pseudo Random Number Generator (PRNG).

My aim was to build a PRNG that:

  1. Is easier to use
  2. Avoids all those duplicate "random" numbers when using the Randomize and Rnd methods,
  3. DOESN'T use or rely on Randomize and Rnd (for anything),
  4. Doesn't rely on Internal Random Number tables,
  5. Produces acceptable randomness (see the test result below), and
  6. Gives me peace of mind.

The Issues

Issue 1: Seeds are crucially important to getting a good random number, and it is difficult to find good seeds. Typical seeds such as current time, number of clock ticks since reboot, process ID or user input, produce only a limited number of random bits.

Issue 2: Some protocols are such that they can "leak" some details of the PRNG state. Given the deterministic nature of the PRNG, this can compromise security unless reseeding is carried out appropriately. In other words: other people could figure out the random numbers you used.

Issue 3: When you are generating Random numbers - using your most complex algorithm-, things may look good and things might look random, but are they really??

Importance of Random Numbers

Random numbers are fundamental to the use of cryptographic mechanisms. The primary uses of random numbers are for key generation and to ensure message uniqueness, which protects against various replay attacks (since many random numbers are not so random as they appear, the chances of figuring out the keys are much better than the odds let you believe). Authentication mechanisms may use a challenge or nonce (a random number) to protect against replay attack.

Confidentiality mechanisms use secret or session keys (derived from a random number) to protect data during a secure exchange. Digital signature mechanisms require large private keys - typically generation of these keys starts with large random numbers (e.g. candidate prime numbers)

Usage

Ensure that you have registered the PRNGMIT.dll file.

VBScript
Set RandomObj = Server.CreateObject("PRNGMIT.prng")
If Err.Number = -2147221005 Or Err.Number = -2147024770 Then
    '=== QDNS.dll is not properly installed ================
    Response.Write "<font color=red>ActiveX Dll not installed!" & _
                   " Please copy PRNGMIT.dll to your "
    Response.Write "permanent Directory and run ""regsvr32 PRNGMIT.dll"" and " & _ 
                   "reboot</font><BR>"
Else
    '=======================================================================
    '===  Purpose: Generate a Random Number within the given limit
    '===  Note:    RND expects LowLimit and HighLimit to be of type LONG.
    '===           In VBScript everything is a Variant, PRNGMIT is 
    '===           strongly typed, so
    '===           ALWAYS Convert -CLng()- your Values in your ASP Pages. 
    '========================================================================
    Dim LowLimit
    Dim HighLimit

    LowLimit = 0
    HighLimit = 10
    Response.Write "Random number between 000 and 010: <B>"
    Response.Write  RandomObj.Rnd(Clng(LowLimit), _ 
                     Clng(HighLimit)) & "</B><BR>"
    Response.Write "Random number between 000 and 100: <B>" 
    Response.Write  RandomObj.Rnd(Clng(0), Clng(100)) & "</B><BR>"
    Response.Write "Random number between -314 and 786: <B>" 
    Response.Write  RandomObj.Rnd(Clng(-314), Clng(786)) & "</B><BR>"
End If

Batteries of statistical tests for Random Numbers

However complex the PRNG is (or the method you made), it remains deterministic in its nature (...Life is just full of patterns). Theoretically, the sequence of random numbers will cycle after a (large) period. It is crucial to check how good the method is you are using. To check this, there is a battery of tests.

For Batteries of Statistical Tests for Random Number Generators see The National Institute of Standards and Technology website.

ENT A Pseudorandom Number Sequence Test Program

See: http://www.fourmilab.ch/random/.

Using this ENT test program to measure the Randomness of our MEELIX PRNG returned the following results:

Entropy = 7.999403 bits per byte.

Optimum compression would reduce the size of this 11468800 byte file by 0 percent.

Chi square distribution for 11468800 samples is 9483.75, and randomly would exceed this value 0.01 percent of the times.

Arithmetic mean value of data bytes is 127.4783 (127.5 = random). Monte Carlo value for Pi is 3.141356425 (error 0.01 percent). Serial correlation coefficient is 0.000090 (totally uncorrelated = 0.0).

The DIEHARD Test Suite

See: http://stat.fsu.edu/~geo/diehard.html.

Using this DIEHARD Test Suite to measure the Randomness of our MEELIX PRNG returned the following results.

The Quick and Dirty Test

This test is based on taking the average of many numbers. If there are no skews, it should give a nice average of 0.5000....etc. Due to rounding problems, you never get the perfect 0.500000000000000.

The result of runs of 25,000, 40,000 and 100,000 random numbers with our MEELIX PRNG are shown below:

 25,000: 0.500025832288101
 40,000: 0.499552333479141
100,000: 0.500056488310338
    Min: 0.000007182771611 (this is the smallest number from our run)
    Max: 0.999989915832831 (this is the largest number from our run)

Guarantees: None

I make no claim about my MEELIX PRNG whatsoever, nor that it generates good random numbers, nor that the source code works as it is supposed to do (whatever that may be).

In short: You may use and distribute this ActiveX DLL/code free of charge, but you may not charge for it or present it as your own work. This notice should be retained. All software/code is provided WITHOUT WARRANTY either expressed or implied. If you find any bugs in this code, please notify the author. This code is provided "AS-IS" - if it doesn't work, we accept no responsibility, nor do we give support (hey, it is FREE).

© Copyright 2001 Meelix Information Technology, All rights reserved.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDieHard Test Results Pin
Member 1610430929-Sep-23 22:27
Member 1610430929-Sep-23 22:27 
QuestionI also ran a test with DieHard. Is this a pass or fail? Pin
Member 1610430929-Sep-23 11:13
Member 1610430929-Sep-23 11:13 
QuestionNow suddently PRNGMIT returns 1 every time!? Pin
holdnukaeft20-Aug-09 3:15
holdnukaeft20-Aug-09 3:15 
AnswerRe: Now suddently PRNGMIT returns 1 every time!? Pin
Michael Meelis20-Aug-09 3:26
Michael Meelis20-Aug-09 3:26 
Generalarticle should be removed. Pin
fresi14-Feb-09 13:47
fresi14-Feb-09 13:47 
GeneralRandom numbers should not be generated with a method chosen at random Pin
Jeffrey Walton2-Jan-07 23:01
Jeffrey Walton2-Jan-07 23:01 
GeneralThis is NOT a PRNG Pin
Member 5102921-Aug-05 15:38
Member 5102921-Aug-05 15:38 
GeneralRe: This is NOT a PRNG Pin
Anonymous21-Aug-05 22:27
Anonymous21-Aug-05 22:27 
GeneralRe: This is NOT a PRNG Pin
Bret Mulvey8-Nov-05 12:26
Bret Mulvey8-Nov-05 12:26 
GeneralRe: This is NOT a PRNG Pin
gussalto10-Nov-06 10:47
gussalto10-Nov-06 10:47 
GeneralIt fails the chi-square test, badly Pin
Bret Mulvey9-Aug-04 12:51
Bret Mulvey9-Aug-04 12:51 
GeneralRe: It fails the chi-square test, badly Pin
Bret Mulvey9-Aug-04 16:24
Bret Mulvey9-Aug-04 16:24 
GeneralRe: It fails the chi-square test, badly Pin
Anonymous9-Aug-04 21:19
Anonymous9-Aug-04 21:19 
GeneralRe: It fails the chi-square test, badly Pin
Bret Mulvey10-Aug-04 7:23
Bret Mulvey10-Aug-04 7:23 
GeneralRe: It fails the chi-square test, badly Pin
Michael Meelis10-Aug-04 9:57
Michael Meelis10-Aug-04 9:57 
GeneralRe: It fails the chi-square test, badly Pin
Bret Mulvey11-Aug-04 5:42
Bret Mulvey11-Aug-04 5:42 
GeneralAuthorization to use your component in my dissertation Pin
Rodney Viana2-Aug-04 6:45
Rodney Viana2-Aug-04 6:45 
GeneralRe: Authorization to use your component in my dissertation Pin
Anonymous3-Aug-04 2:07
Anonymous3-Aug-04 2:07 
Generalrandom password Pin
Anonymous15-Dec-03 19:34
Anonymous15-Dec-03 19:34 
GeneralLatest version Pin
Michael Meelis4-Jun-02 22:58
Michael Meelis4-Jun-02 22:58 
GeneralUse PRNGMIT in a stress test environment Pin
4-Jun-02 14:45
suss4-Jun-02 14:45 
GeneralRe: Use PRNGMIT in a stress test environment Pin
Michael Meelis4-Jun-02 22:54
Michael Meelis4-Jun-02 22:54 
GeneralSource code now available! Pin
29-Apr-02 2:12
suss29-Apr-02 2:12 
QuestionIs it really any better? Pin
Andrew Phillips13-Jun-01 18:32
Andrew Phillips13-Jun-01 18:32 
Since you don't tell us anything about the algorithm you use, why would anyone believe it is any better than the normal Rnd function?

Actually Rnd is adequate for a lot of tasks. It has a long enough cycle for simple random number generation as would be most commonly used in this sort of language. It is very fast. A minor problem with this type of algorithm is that the least significant (2 or 3) bits are not random but these should be thrown away anyway.

It is misleading to say it is table based. The number 16,777,216 (which is 2^24 NOT by coincidence) is just the cycle. I guess you can think of it as a very big table but there is no physical table in memory or on disk.

The way Rnd and Randomize works are by design. If you don't call Randomize (or call it with the same number for each run) you get the same sequence of random numbers -- this is essential for reproducibility during testing. If you want different random numbers each time use the current time as a seed.


Seeds
------

You say that seeds are an issue but you don't seem to address that issue. For simple apps you can just use the current time. For apps with tougher requirements, you can use a combination of time (in msecs), keyboard latency (time between keypresses), a random number table (you can probably buy CDs full of random numbers), and even special hardware that uses quantum randomness.


Security
--------

If you have an application where it should be impossible to predict the next random number in a series (eg, lotto results) then you need something more sophisticated than Rnd. You need to use real random numbers (using special hardware) or at least a PRNG with a very large cycle. I doubt that this sort of application is written in VB.


Randomness
------------

I agree that what looks random may not be. In fact a PRNG by definition cannot produce random numbers.


Tests
-----

Statistical tests prove nothing. Algorithms have been invented that passed all known statistical tests but when scrutinized new tests were invented that showed their weakness.

Rather than inventing an algorithm and testing it, why not just use a known, proven algorithm. More important is probably to understand the application and choose an algorithm that is appropriate.

Aims
----

You state that your aims are a PRNG that:

> Is easier to use

What could be easier than a function to get a random number and another to reseed the generator? (Rnd, Randomize)

It's nice to have extra facilities, like returning a number within a range etc, but this can just be a wrapper.

> Avoids all those duplicate "random" numbers when using the "Randomize" and "Rnd" method,

Every PNRG has a cycle. You cannot avoid having duplicate numbers.

> DOESN'T use or rely on "Randomize" and "Rnd" (for anything),

This is not a worthwhile aim, unless Rnd is insufficient for the particular needs of the application.

> Doesn't rely on Internal Random Number tables,

There is no internal table. The number 16,777,216 is just the cycle of the PRNG used by VB.

> produces acceptable randomness (see the test result below), and

What is acceptable depends on your application.

> gives me peace of mind.

This is best achieved by understanding your application and the limitations of Rnd.


Conclusion
----------

I think the point is that for simple uses Rnd is adequate. If you have a need for better random numbers find a known good algorithm and implement it yourself. Then verify it is working correctly, based both on the expected output and statistical tests.

If you don't want to implement it yourself find an implementation that uses a known good algorithm that suits your needs. If security is an issue make sure it is provided in the form of source code.

Andrew.


Andrew Phillips
andrew @ expertcomsoft.com
AnswerRe: Is it really any better? Pin
19-Jun-01 0:22
suss19-Jun-01 0:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.