Asked by:
How do I show the Seed value for Randomize?
Question

Hi Everyone:
I am playing around with Random Numbers.
When generating a Random number the statement Randomize() initializes the random number generator with a seed.
The Seed is based on the System Timer with Seed>0 and Seed<1.
How can I find the Seed value based on the System Time?
Thanks,
MRM256
 Moved by KareninstructorMVP Friday, September 13, 2019 6:43 PM Moved from vb.net forum
All replies


Hi Les,
I am trying to do a simple reverse of a Random number.
I have the following code:
Public Function Rnd_Pick5_Num(ByVal Lower As Integer, _ ByVal Upper As Integer, _ Optional Seed As Double = 0) As Integer 'Generates a Random Number BETWEEN the LOWER and UPPER values Randomize (Seed) 'Rnd_Pick5_Num = Int((Upper  Lower + 1) * Rnd + Lower) Rnd_Pick5_Num = Int(((Upper + 1)  Lower) * Rnd + Lower) 'Rnd_Pick5_Num = Round((Upper + 1  Lower) * Rnd + Lower) End Function
I have the following set of random numbers: 11, 20, 41, 42, 56, 6.
According to my research(could be in error) Windows uses the Linear Congruential Generator to generate random numbers. The formula for this is X1 = (X0*a+c) mod m. I wrote a function to simulate this:
' ' Function Linear Congruential Generator Date: 28Aug2019 ' Public Function frmlLCG(Optional Seed As Long = c) As Long 'Purpose: Suppost to be RNG function in Access VBA 'Parameters: frmlLCG() = returned value ' m = modulus = (2 ^ 24) ' x1 = New Value ' x0 = previous value (initial value 327680) ' a = 1140671485 ' c = 12820163 ' Repeat length: m = (2 ^ 24) = 16,777,216 'Returns: A Randon number calculated using the ' Equation: X1 = (X0 * A + C) Mod c On Error GoTo frmlLCG_Err Dim X0 As Long, _ X1 As Long X1 = (X0 * a + c) Mod m frmlLCG = X1 frmlLCG_Exit: On Error Resume Next Exit Function frmlLCG_Err: Call LogError(Err.Number, _ Err.Description, _ "modFunctions: Function frmlLCG", _ Now) Resume frmlLCG_Exit End Function
Mathematically, I should be able to provide one of the generated random numbers and derive its seed.
I don't want to write a new class for something that be solved using algebra.
Thanks,
MRM256


You could specify the seed value in the constructor yourself so can then work backwards from that result?
dim rand1 as new random(100)
Wild guess: the system clock seed could be just the value of now.ticks? Can you try that? Its actually accurate to 15ms intervals or so on a pc I believe.
Date.Now.Ticks
"The value of this property represents the number of 100nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar),"
 Edited by tommytwotrain Monday, September 9, 2019 9:59 PM



Hi Tommytwotrain:
Because the seed must be >0 and <1 how would this be represented in ticks?
Thanks
MRM256
M,
Where do you get that idea?
Do you mean you want to use 01 for seeds?
Are you using vb.net? There is a new function Random(). I read the Random() takes an integer or double for the seed. So you should be able to use either?
See the example at the end of this:
https://docs.microsoft.com/enus/dotnet/api/system.random.ctor?view=netframework4.8
see how the 3 seed examples at the bottom. Two are given the same seed (int) and return the same result. The 3rd has a different seed and different results.
As far as the ticks fo that is a unit and the value is a real number +infinity.infinty
see the example at the end here:
https://docs.microsoft.com/enus/dotnet/api/system.datetime.ticks?view=netframework4.8"If run on December 14, 2007, at 15:23, this example displays the
' following output to the console:
' 219,338,580,000,000,000 nanoseconds
' 2,193,385,800,000,000 ticks"Normally when you call the .ticks method you get a real big integer.
PS I am not saying you need to use ticks for anything I just guess that when you call random with no seed and vb makes its own seed the value might be now.ticks or some function of that. You might be able to try it and work backwards and if your forumula works the same as vb then vb is using ticks since midnight year zero. Comprende?
But regardless you can test your code using your own seed ie random(142)?
:)
PS if you mean your math formula takes 01 seeds then I guess you need to divide by 1000 or something? I don't know? Lets see your formula.
Try random(double) ie random(0.142)? I think I read it will take double?
PS No sorry it generates int or double. So you need to explain what you mean 01.
PS Oh I see you mean math.randomize. Hmmm. I don't know. Have I given you any ideas?
Your function code takes a long?
Function frmlLCG(Optional Seed As Long = c) As Long
Sorry I did not read well. Is that vb6 code you posted?
 Edited by tommytwotrain Tuesday, September 10, 2019 11:14 AM

Hi TommyTwoTrain,
No, this is VBA  Visual Basic for Applications; it is based on VB6. FYI  this is the code used in the Macros for all office applications; Word, Excel, Access, and so on.
From what I understand most pseudo random number generation functions require a 'seed' value for initialization. By definition this value is a decimal fraction that must be greater than zero, but less than one. If you initialize using a value of zero or nothing then the seed is derived using the system timer.
For example: ? time & vbtab & cdbl(time) returns 8:51:49 AM 0.36931712962963. As you can see the system time is a value greater than zero and less than one.
Using the formula for a standard Linear Congruential Generator I tried to derive the a formula that would tell me the seed value if I gave it one of the numbers returned by the RNG function. This didn't work; my function is flawed.
PS  I got this from the Microsoft Docs to help you.
The Rnd function returns a value less than 1 but greater than or equal to zero.
The value of Number determines how Rnd generates a pseudorandom number:

For any given initial seed, the same number sequence is generated because each successive call to the Rnd function uses the previous number as a seed for the next number in the sequence.

Before calling Rnd, use the Randomize statement without an argument to initialize the randomnumber generator with a seed based on the system timer.
Thanks,
MRM256
 Edited by MRM256 Tuesday, September 10, 2019 2:19 PM better understanding


Hi TommyTwoTrain,
No, this is VBA  Visual Basic for Applications; it is based on VB6. FYI  this is the code used in the Macros for all office applications; Word, Excel, Access, and so on.
From what I understand most pseudo random number generation functions require a 'seed' value for initialization. By definition this value is a decimal fraction that must be greater than zero, but less than one. If you initialize using a value of zero or nothing then the seed is derived using the system timer.
For example: ? time & vbtab & cdbl(time) returns 8:51:49 AM 0.36931712962963. As you can see the system time is a value greater than zero and less than one.
Using the formula for a standard Linear Congruential Generator I tried to derive the a formula that would tell me the seed value if I gave it one of the numbers returned by the RNG function. This didn't work; my function is flawed.
PS  I got this from the Microsoft Docs to help you.
The Rnd function returns a value less than 1 but greater than or equal to zero.
The value of Number determines how Rnd generates a pseudorandom number:

For any given initial seed, the same number sequence is generated because each successive call to the Rnd function uses the previous number as a seed for the next number in the sequence.

Before calling Rnd, use the Randomize statement without an argument to initialize the randomnumber generator with a seed based on the system timer.
Thanks,
MRM256
I see. This is the vb.net forum. You might ask at the vbforums.com has vb6 etc.
In .net it is different. Time different, new random() different. There is rnd but it is different from random.
However I can see where that decimal fraction you calc from your time mins secs could have error like + 0.00000000000009 (double accuracy) or even a completely different way of doing something from what vba might calc.
Plus one saves the seed time value to test with but by the time you saved it, it may have changed from what vba used. Plus I tell you the system timer on a windows pc is accurate to 15 ms. That is what the example above shows. So that is your accuracy trying to do it with the time.
But thats all irrelevant since in this forum we use vb.net.
I suspect if you use vb.net random with an integer seed as shown in the examples above you will get the accuracy you need to test your method. The examples I pointed out above show that? But I dont really know I have not done it.
Why dont you do it vb.net? Do you have some thing for doing vba?
PS Oh wait maybe vb.net does not use the same math eq for random?
 Edited by tommytwotrain Tuesday, September 10, 2019 3:07 PM


Why aren't you using the Random Class? It is the replacement for Randomize / Rnd.
Multics  An OS ahead of its time.
"Those who use Application.DoEvents have no idea what it does
and those who know what it does never use it." former MSDN User JohnWein



I am storing the numbers in an Access database so I can do some analytics. I need to use VBA for this.
Where is the formula/algorithm for the Random number generator class?
Thanks,
MRM256
https://docs.microsoft.com/enus/dotnet/api/system.random?view=netframework4.8
"RemarksPseudorandom numbers are chosen with equal probability from a finite set of numbers. The chosen numbers are not completely random because a mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. The current implementation of the Random class is based on a modified version of Donald E. Knuth's subtractive random number generator algorithm. For more information, see D. E. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. AddisonWesley, Reading, MA, third edition, 1997. "
..."Substituting your own algorithmYou can implement your own random number generator by inheriting from the Random class and supplying your random number generation algorithm. To supply your own algorithm, you must override the Sample method, which implements the random number generation algorithm."
Oh here is what you need in .net?"Random.Sample Method
Returns a random floatingpoint number between 0.0 and 1.0."

For what it is worth:
I found a C++ program that runs the Linear Congruential Generator from tutorialspoint.com. I had to see how the LCG algorithm functioned, so I could understand it better.
#include <iostream> using namespace std; class mRND { public: void seed(unsigned int s) { _seed= s; } protected: mRND() : _seed(0), a(0), c(0), m(2147483648) { } int rnd() { return (_seed = (a * _seed + c) % m); } int a, c; unsigned int m, _seed; }; class MS_RND: public mRND { public: MS_RND() { a = 214013; c = 2531011; } int rnd() { return mRND::rnd() >> 16; } }; class BSD_RND: public mRND { public: BSD_RND() { a = 1016404597; c = 12345; } int rnd() { return mRND::rnd(); } }; int main(int argc, char* argv[]) { BSD_RND bsd_rnd; MS_RND ms_rnd; cout << "MS RAND:" << endl << "" << endl; for (int x = 0; x < 6; x++) cout << ms_rnd.rnd() << endl; cout << endl << "BSD RAND:" << endl << "" << endl; for (int x = 0; x < 6; x++) cout << bsd_rnd.rnd() << endl; return 0; }
If I am looking at this right; X0 = 0 because unless there is a seed value supplied (0 mod 2147483648 ) is 0. The values a and c determine the sequence.MRM256

I dont know. I dont think I understand what you mean or how it works exactly anyway etc.
In the mean time I ended up with this version of the LCG.
I found this c# which I converted to vb.net and its duplicating the results from the last post on the thread:
It appears the author is using primes for seeds from the list in the class which is why it repeats and the commenter mentions etc. If one follows it each round of the loop it uses the next prime. See how its using the next function?
Maybe you can use it somehow.
Imports System Imports System.Collections.Generic Public Class Form4 Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim rng As RandomNumber = New RandomNumber(42) Dim result As String = "" For i As Integer = 0 To 10  1 result &= rng.[Next](0, 9).ToString & " " Next ' correct answer 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 MsgBox(result) End Sub End Class 'Namespace FULLCYCLE 'https://stackoverflow.com/questions/3935365/howtowritealinearcongruentialgeneratorlcgincorarethereanywell Public Class RandomNumber Private _value As Integer Private _prime As Integer Private Shared primes As List(Of Integer) = New List(Of Integer) From { 11, 23, 47, 97, 797, 1597, 6421, 25717, 51437, 102877, 411527, 823117, 1646237, 3292489, 6584983, 13169977, 26339969, 52679969, 105359939, 210719881, 421439783, 842879579, 1685759167 } Public Sub New(ByVal seed As Integer) _prime = primes(seed Mod primes.Count) _value = seed End Sub Public Function [Next](ByVal min As Integer, ByVal max As Integer) As Integer Dim maxrate As Integer = max  min + 1 If _value > maxrate Then _value = _value Mod maxrate End If _value = (_value + _prime) Mod maxrate Return _value + min End Function End Class 'End Namespace


Hi Tommy,
From what I read of the LCG it takes the last number generated and uses it as the seed for the next number.
You wouldn't happen to know of a website that already have the functions for Random Number Generators already coded?
Thanks,
MRM256
No sorry, I did not see a web site with that code perfectly laid out as you desire (not sure what that is? :) ) other than the odds and ends that show c# code I saw when searching. c# is easily converted to vb.net using online converter.
The Wikipedia had a good write up. I see pascal, c++, c#. What lang do you want?
Is there something wrong with the vb.net code I posted last above? It seems to be working?
See how you declare
Dim rng As RandomNumber = New RandomNumber(42)
in the example and then the last rng._value is reused 9 times in the loop calling the next function?
See where is takes seed = 42 in the new contstructor and that is saved in the class as
_value = seed ?
the _value is reused each time through the loop in the next function. Checked and modified with max mins...
Is that what you mean?
I the example saves the last _value and uses it in current rng._value unless you use the new contructor to make a new instance of the class (ie rng) with a new seed and therefore new rng._value.
Is that not how the RandomNumber function I posted above is working? Or am I missing something?
PS If I declare rng instance Public at class level then you can just seed it once and the class will always reuse the last rnd._value when you call the next function unless it is out of the max min rang then it plays games for the first one. But after than it is saved and reused in the class instance.
Correct?
Plus that is how the new .net Random() class works with reusing the class instance and next.
Les et al am I seeing it right?
 Edited by tommytwotrain Thursday, September 12, 2019 10:49 PM

If this is VBA it should be moved
Multics  An OS ahead of its time.
"Those who use Application.DoEvents have no idea what it does
and those who know what it does never use it." former MSDN User JohnWein

Seems this thread is better off in the VBA forum yet the move function is currently not available and will move this thread once move is available again.
Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
NuGet BaseConnectionLibrary for database connections.


Hi Tommy,
First off there is nothing wrong with the VB.NET LCG code. The reason I asked if you knew any website that already had code written for PRNGs is because I am trying to reverse engineer the Seed by using a RND generated result.
This link shows a list of different PRNGs: https://en.wikipedia.org/wiki/List_of_random_number_generators
If you have an equation and you need to solve for a different variable. This can easily be done using algebra. A good example is the Fahrenheit to Celsius.
My algebra teacher had us memorize the Fahrenheit formula: (32°F − 32) × 5/9 = 0°C then have us derive the Celsius formula. In other words solve for C.
I want to do the same for the PRNG equations, but I am having a tough time chasing them down.
FYI  I am an old fart. We didn't have the Internet to do our math conversions for us. :).
Thanks,
MRM256

Hi Tommy,
First off there is nothing wrong with the VB.NET LCG code. The reason I asked if you knew any website that already had code written for PRNGs is because I am trying to reverse engineer the Seed by using a RND generated result.
This link shows a list of different PRNGs: https://en.wikipedia.org/wiki/List_of_random_number_generators
If you have an equation and you need to solve for a different variable. This can easily be done using algebra. A good example is the Fahrenheit to Celsius.
My algebra teacher had us memorize the Fahrenheit formula: (32°F − 32) × 5/9 = 0°C then have us derive the Celsius formula. In other words solve for C.
I want to do the same for the PRNG equations, but I am having a tough time chasing them down.
FYI  I am an old fart. We didn't have the Internet to do our math conversions for us. :).
Thanks,
MRM256
Mrm,
"I want to do the same for the PRNG equations, but I am having a tough time chasing them down."
Oh. Ok. Well you need to show us the math algorithm you want to code and then we can help with the vb.net code. Otherwise technically it is off topic.
@ Karen and dbas it seems OP just wants to see a coded equation and just learn the non lang specifics? and then I am not sure when the vba comes in. If you look at OPs activity there is plenty vb.net so I dont know if it matters vba or vb.net. And OP is not sayin? I am just following along for the fun of it?
 Edited by tommytwotrain Friday, September 13, 2019 6:10 PM

Tommy,
This topic drifted way off target. All I want was a equation similar to the Linear Congruential Generator which given a RNG result it would tell you the system time when it was generated.
For example: You asked for a random number like X=RND() and it returns 42. To find the time value you would put in Y=RND^1(42) and it would return a time value like 0.12345 the single value of time on the PC.
It looks like we might have to delete this topic.
Thanks,
MRM256