Re: how to generate random string?

"Dr John Stockton" <jrs@xxxxxxxxxxxxxxxxxx> wrote in message
JRS: In article <ukNHkjg2GHA.1040@xxxxxxxxxxxxxxxxxxxx>, dated Sat, 16
Sep 2006 22:25:11 remote, seen in news:microsoft.public.scripting.vbscri
pt, Richard Mueller <rlmueller-NOSPAM@xxxxxxxxxxxxxxxxxxxx> posted :


Documentation says that Randomize seeds the Rnd function with a value from
the Timer function. The Timer function returns the number of seconds since
midnight, to the nearest 100th of a second. The values range from 0.00 to
86400.00, so 8,640,000 values.

You mean 86399.99, 8,639,999.


No, the Timer returns the number of seconds, reported as a multiple of
0.01 seconds. It does not necessarily change every 0.01 seconds; in my
system it updates at 18.2 Hz, so takes steps of 5 or 6 in the second
decimal place. In other systems it does update faster.

I expected the same, since the system timer ticks 18.2065 times per second.
Before I posted I tested on a Pentium 3 system and found that the output
incremented in 0.01 seconds. However, the OS was w2k. I also tested on an XP
system. After your posting I tested again on an identical Pentium 3, but
with Win98, and Timer incremented in larger intervals. Same on a Pentium 4
with Win98. Interesting.

Rnd itself is said to be a 24-bit Linear Congruential Generator of maximal
length, so it can generate 16,777,216 (2^24) different values. However,
7 digits are displayed.

Rnd surely generates an IEEE Double, capable of 53 bit resolution but in
this case presumably using only 24. It is conversion-to-string which
gives values with 7 or fewer decimal places or in E-format. I see, for

document.write "<pre>"
for K = 1 to 50
R = Rnd
document.write R, " ", R*16777216, "<br>"
document.write "</pre>"
to see that the results of Rnd do effectively have 24 significant bits.

I find that Rnd * 16777216 is always an exact integer.

To be sure of getting equi-probable digits, one must either use Rnd as a
number in 0..1 or, if going via string, think rather carefully.

Also disappointing, since it has for many years been very practical to
use a generator with 32 bits. ISTR that Turbo Pascal had such in the
late 1980s.

If the application needs good Randoms, one can use javascript, or write
one's own - follow Knuth or my pas-rand.htm

It seems that VB and VBScript are limited to 15 decimal digits. I think that
is why they limit the LCG to 24 bits. I agree this is disappointing. In
assembly it is straightforward to create a 64-bit LCG, even using 32-bit
registers. Years ago I created a psuedo random number generator in assembly
with a period of about 2^222 (in theory at least, based on Knuth).

I find the Rnd function is equivalent to the following function, divided by
16777216 and rounded to 7 digits. In the snippet below I do not round the
output of my function to 7 digits:
' Constants for Linear Congruential Generator.
Const A = 16598013
Const C = 12820163
Const M = 16777216

' Initialize with any seed.
' x is series created by Rnd.
' y is series created by Function LCG.
x = Rnd
y = x * M

' Output next 50 numbers from each.
For = 1 To 50
x = Rnd
y = LCG(y)
Wscript.Echo x & ", " y / M

Function LCG(lngSeed)
LCG = A * lngSeed
LCG = (LCG - Fix(LCG)) * M
End Function
My function LCG must use the integers or it won't work. Rounding to 7 digits
after dividing by M is not easy. For example, 0.008614659 is not rounded to

I have not figured out what the Randomize function does. It accepts any
number you give it. I have not been able to find a value to pass to
Randomize that duplicates what it does when you do not pass a value to it.
For example, Randomize(Timer) is not equivalent to Randomize().

Microsoft MVP Scripting and ADSI
Hilltop Lab -