/*
Random binary file creator By Dale Swanson Nov 19 2006
Basicly this creates a huge ( 12 MB) binary file of random 1's and 0's.  If you open it up you won't see 1's and 0's, you'll see garbage, because it's stored as bits, not bytes, if you don't get it whatever, not important.
The basicly only reason for this it to use the Diehard test program to test you RNG, my current one passes all test, and is about 80% slower than the stock one, and I feel it is probably at least fairly safe for cyrpto.
*/

//I have no idea which of these headers I actually need, and I don't care
#include <stdio.h>  /* header file  */
#include <stdlib.h>
#include <cstdlib>
#include <iostream>
#include <fstream.h>
#include <math.h>

using namespace std;

char basen[100] = "R";
char ext[10] = ".bin";
char fname[100];

double ran(double a, double b) //returns a random number between a min, and b max
{
	int k; //used for killing some random numbers (k is a random letter I picked, but let's pretend I picked it to stand for kill)
	double range; //range from you min and max
	double c = 0; //this is your real random number that will be used to return
	range = (b - a) + 1;
	if (rand() == 138) srand(rand() + clock()); 
	//1 in 32k odds to reseed the RNG uses both a rand number and the clock (clock isn't seconds, it's system ticks, faster than seconds) 
	if ((rand() + clock()) % 5 == 1) 
	//basicly 1 in 5 chance of looping a wasting some random numbers
	{
		for (k = ((clock() % 4) + ((rand() + clock()) % 7) + (rand() % 18) + 9); k > 0; k--)//comes up with a number to loop from about 9 to 35 times
		{
			rand(); //wastes some random numbers
		}
	}
	c = a + int(range * rand() / (RAND_MAX + 1));
   return c;
}

void fnamecomb() //combines basen + the time + ext into fname
//requires the global char's basen, ext, fname
{
	time_t tsec; //sets time to tsec
	time(&tsec);
	int tnum;
	char sttim[100];
	tnum = int(tsec);
	
	itoa(tnum, sttim, 10); //sets the string sttime to the value of the current time
	strcpy (fname, basen); //combines the 3
	strcat (fname, sttim);
	strcat (fname, ext);
	return;
}

int main(int argc, char *argv[])
{
	int rannum[35];
	int x;
	unsigned int outnum;
	int bprint;
	int byts;
	
	fnamecomb();
	
	cout<<"\nFile name is - "<<fname<<"\n";
	
	FILE *fp;   /* file pointer */
	fp = fopen(fname, "ab");
	
	cout << "\nHow many 8 bit (1 byte) numbers, 138 for 12M ";
	cin >> byts;
	if (byts == 138) byts = 12000000;

    time_t sseconds; //creates the start time varible, will be used as intitial seed
	time_t cseconds; //current seconds, will be used for length of time
    time(&sseconds);
    srand(clock() + sseconds); //intital seed
	
	cout<<"\nStarting..."; //the next bunch of if are just for displaying progress
	for (bprint = 1; bprint <= byts; bprint++)
	{
		if (bprint == byts / 10)
		{
			time(&cseconds);
			cout<<"\n10% Time - "<<cseconds - sseconds;
		}
		else if (bprint == byts / 4)
		{
			time(&cseconds);
			cout<<"\n25% Time - "<<cseconds - sseconds;
		}
		else if (bprint == byts / 2)
		{
			time(&cseconds);
			cout<<"\n50% Time - "<<cseconds - sseconds;
		}
		else if (bprint == byts)
		{
			time(&cseconds);
			cout<<"\n100% Time - "<<cseconds - sseconds;
		}
		
		outnum = 0; //this is where the actual work is done
		for (x = 1; x < 9; x++)
		{
			rannum[x] = ran(0, 1); //just sets the current number in the array to either 0 or 1
			outnum = outnum + (pow(2, x - 1) * rannum[x]);
			//this forumla adds up the binary number as it's found.
			//it uses the number's place in the array minus 1 as the power of 2 to find the value that a 1 in that spot would have
			//so it's 1, 2, 4, 8, 16, 32, 64, 128
			//it does use the number basicly backwards, but I just didn't feel like having it go from right to left, just more complication, and no real benifit
			}
		//size_t fwrite(void *buffer, size_t size, size_t num, FILE *fp);
		fwrite(&outnum, 1, 1, fp); //writes the decimal number stored in outnum to the file, in it's binary form
	}

	cout<<"\nDone\n";
    system("PAUSE");
    return EXIT_SUCCESS;
 
 
}
