I need to emulate VB's Rnd and Randomize functions, for use in other languages. The Rnd function is not a problem and I have code which works fine in several languages for the default true start seed (327680) - a quick test of the first million or so decimal random numbers from this seed agrees exactly with the VB's own Rnd output.
The problem is that I need to be able to specify the start seed and Randomize hashes the seed it is given into a "true" seed. I've searched the internet for hours but cannot find any documentation that specifies how it does it - except for one article
( http://www.15seconds.com/issue/051110.htm )
which is incorrect! This article states that:
The Single (datatype) seed is 'moshed' into 2-byte seed (TwoByteSeed) value with the following XOR operations:
TwoByteSeed = [byte1 XOR byte3] [byte2 XOR byte4];
One additional XOR operation is performed on these two bytes, depending on the sign of the originally supplied seed as the following code snippet describes:
If originalseed < 0 Then
TwoByteSeed = TwoByteSeed XOR &h06C0
TwoByteSeed = TwoByteSeed XOR &h0240
This is demonstrably incorrect because offering a seed with a specific value in byte2 (with the other bytes all zero) should give exactly the same true seed as offering a seed with the same specific value in byte 4 (again with the others all zero). It doesn't, although the binary values do have marked similarities, and the additional XOR doesn't work either. However, I do think that the article may be partially correct.
I have a small program which will search and discover what the true seed is for any Randomize seed (the true seed being the one which produces the correct VB Rnd output) but despite having generated hundreds of examples I still can't work out how Randomize manipulates the bits of the input seed to get the true seed. I do know that it adds a third fixed byte onto the end of the twobyte "hashed" seed (the byte value is 10000110b).
My analytical skills have let me down here, and not being a coding expert I have no idea how to find or disassemble the VB Randomize source.
That would be 'hacking' I'd guess. Not allowed over at this forum. Why do you ask? This is a programming forum.
Also, that article talks about VB.Net and this is the VB6 forum.
Well, I'm not a hacker! As I said, I'm writing a program which I want to be portable, and I don't want to use the VB built-in Randomize function, just emulate it. There doesn't seem to be any secret about how Rnd works (MS publish it), just the Randomize bit. The article I mentioned covers Visual Basic in general, and the same function is almost certainly used in both VB6 and VB.Net.
Originally Posted by WoF
I always thought Randomize takes the value of the system time to produce a unique sequence of random numbers...
If you don't use Randomize the seed default is 327680;
if you just use Randomize on its own, WITH OR WITHOUT a parameter, the session time is used as a seed (for Vista and Win7 it is the time elapsed since your session started, not the system clock, I believe - but I don't know about XP);
if you perform Rnd(-1) then Randomize(n) the seed that is used is 'n' but it is hashed first, and it is the hashing subroutine that I am trying to work out.
Sorry if I've stepped on a toe or two here - I'm just a hobbyist programmer (I do admit that I'm an OAP) trying to solve a problem.