This is a very basic Pick 5/36 C++ program:
// BOF
#include <iostream>
#include <iomanip>
#include <fstream>
#include <ctime>
using namespace std;
int Num1 = 0;
int Num2 = 0;
int Num3 = 0;
int Num4 = 0;
int Num5 = 0;
void PickNumbers();
void SortNumbers();
int main()
{
ofstream outFile("QuickPicks.txt", ios::app);
if(outFile.fail())
{
cerr << "outFile error" << endl;
exit(1);
}
int count = 0;
srand(time(0));
for(;;)
{
cout << "How many Quick Picks would you like to print(0 to exit)? ";
cin >> count;
cout << endl;
if(count != 0)
{
for(int i = 1; i <= count; i++)
{
PickNumbers();
cout << setw(2) << Num1 << " "
<< setw(2) << Num2 << " "
<< setw(2) << Num3 << " "
<< setw(2) << Num4 << " "
<< setw(2) << Num5 << endl;
outFile << setw(2) << Num1 << " "
<< setw(2) << Num2 << " "
<< setw(2) << Num3 << " "
<< setw(2) << Num4 << " "
<< setw(2) << Num5 << endl;
}
}
else
{
break;
}
cout << endl;
}
outFile.close();
return 0;
}
void PickNumbers()
{
do
{
Num1 = rand() % (36 - 1 + 1) + 1;
Num2 = rand() % (36 - 1 + 1) + 1;
Num3 = rand() % (36 - 1 + 1) + 1;
Num4 = rand() % (36 - 1 + 1) + 1;
Num5 = rand() % (36 - 1 + 1) + 1;
}while(Num1 == Num2 || Num1 == Num3 || Num1 == Num4 || Num1 == Num5 ||
Num2 == Num3 || Num2 == Num4 || Num2 == Num5 ||
Num3 == Num4 || Num3 == Num5 ||
Num4 == Num5);
SortNumbers();
}
void SortNumbers()
{
do
{
if(Num1 > Num2) swap(Num1, Num2);
if(Num2 > Num3) swap(Num2, Num3);
if(Num3 > Num4) swap(Num3, Num4);
if(Num4 > Num5) swap(Num4, Num5);
}while(Num1 > Num2 || Num2 > Num3 || Num3 > Num4 || Num4 > Num5);
}
// EOF
At the beginning of the program, the random number generator is initialized by the srand() function using the argument(the seed) passed to the function. In this case, time(0) is the seed. Now what exactly is time(0)? time(0) returns the number of seconds accumulated since 00:00 January 1, 1970. Why that particular date and time? I have no idea. Now lets pretend that the lottery's software automatically chooses the official winning numbers at EXACTLY 9:00pm(with no pretests) and just for example purposes, they also use time(0) as the only seed just like the code above! Theoretically, would it be possible to determine the numbers that will come out the winners? Yes. Now lets look at what realistically(or at least we hope) happens during an RNG drawing:
1. The program more than likely isn't programmed to choose the winning numbers at EXACTLY(which includes seconds) the official draw time. The program more than likely requires the draw person to click a "Choose numbers" button of some sort. Not only that, but the we have no idea when the RNG is reintialized with a new seed. It could be just when the program starts up, which we have no idea will happen. We don't know if these people are starting the program 5, 10, or 15 or whatever minutes before the drawing takes place. It could also be intialized after an entire set has been chosen, or after a single number has been chosen.
2. We also don't know what other things the lottery uses as a way to initialize its RNG. Which I'll discuss now.
There are indeed ways to make an RNG "more" random. How? By using factors that are constantly changing. For example, the number of bytes of physical memory that are in use by the computer are constantly changing. You could write a function that returns the number of bytes that are in use by the computer at the time the function is called. So instead of initializing the RNG simply as:
srand(time(0));
Suppose I wrote a function that returns the current amount of bytes in use by the system, I could intialize it with one of these:
srand(time(0) * GetPhysicalMemoryUsageInBytes());
srand(time(0) / GetPhysicalMemoryUsageInBytes());
srand(time(0) % GetPhysicalMemoryUsageInBytes());
You could also make it "more" random by using a pseudo-random number as a factor for reseeding the RNG. For example:
srand(time(0) * rand());
Take it another step further, and you could combine both the examples and use something like:
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
So a way I could make the number choosing process of the program above more random, I could replace the PickNumbers() function with something like this:
void PickNumbers()
{
do
{
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num1 = rand() % (36 - 1 + 1) + 1;
Num2 = rand() % (36 - 1 + 1) + 1;
Num3 = rand() % (36 - 1 + 1) + 1;
Num4 = rand() % (36 - 1 + 1) + 1;
Num5 = rand() % (36 - 1 + 1) + 1;
}while(Num1 == Num2 || Num1 == Num3 || Num1 == Num4 || Num1 == Num5 ||
Num2 == Num3 || Num2 == Num4 || Num2 == Num5 ||
Num3 == Num4 || Num3 == Num5 ||
Num4 == Num5);
SortNumbers();
}
Now, the RNG would be reseeded after each SET of numbers, using 3 factors that are constantly changing. Pretty random right? Could I be more obsessive and make it even more random? Sure, instead of reseeding the RNG after each SET is picked, I could reseed it after each NUMBER is picked. So I could change the function to:
void PickNumbers()
{
do
{
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num1 = rand() % (36 - 1 + 1) + 1;
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num2 = rand() % (36 - 1 + 1) + 1;
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num3 = rand() % (36 - 1 + 1) + 1;
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num4 = rand() % (36 - 1 + 1) + 1;
srand(time(0) * rand() * GetPhysicalMemoryUsageInBytes());
Num5 = rand() % (36 - 1 + 1) + 1;
}while(Num1 == Num2 || Num1 == Num3 || Num1 == Num4 || Num1 == Num5 ||
Num2 == Num3 || Num2 == Num4 || Num2 == Num5 ||
Num3 == Num4 || Num3 == Num5 ||
Num4 == Num5);
SortNumbers();
}
That function alone is EXTREMELY random at choosing numbers. Plus, I could even add more things that constantly change as factors. Like the number of total handles, the amount of I/O reads or I/O writes. So many things that are constantly changing on the computer.
This is why I have no problem playing an RNG lottery as far as randomness itself is concerned, ASSUMING all the code within the lottery program is legitimate. HOWEVER, I also don't know if all the code is legitimate, and THAT is why I'm against RNG lotteries. The operation of choosing the numbers are viewable by the player. There are no underlying operations taking place.