Jump to content

Generate a random byte

- - - - -

  • Please log in to reply
4 replies to this topic

#1
irancplusplus

irancplusplus

    Learning Programmer

  • Members
  • PipPipPip
  • 65 posts
Hi
using MSDN help pages, I could write this function for generating a random number:

Quote

#include <windows.h>
#include <wincrypt.h>

unsigned __int8 RandomByte()
{
unsigned __int8 ret;
HCRYPTPROV hProv;
CryptAcquireContext(&hProv,0,0,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
CryptGenRandom(hProv,1,&ret);
return ret;
}
I think it can be simpler. can you suggest a simpler function?
I wrote this ebook! Will you translate it into English for free!?:confused: PM me!

#2
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
You could use the rand() function provide by either the GLIBC or Microsoft MSCRT that should be included automatically, within the stdlib.h header.


number = rand() % 256 //0..255, or 0x00..0xff


It will usually return something between 0, and the macro RAND_MAX so it must have a modulation to tie it down to a specific range. You can always put this logic in a function so that it can be called as myrand(0, 255);


If you require unique sequences per run of the application, you can create a seed for the linear congruential generator with the srand function:
srand(value); //i.e. value = time(NULL) from time.h/ctime.h
__uint8 number = rand() % 256;


Floating point numerics can be freely obtained if desired with this method (0.0 to 1.0 inclusive)
float number = (float) rand() / (float) RAND_MAX;


If a greater period and more uniform distribution is required (if you were creating test data for example) there are many available algorithms that can be implemented within your code, that do not require an external library (such as your wincrypt.h), however the amount of code you have provided is not that large, if you require such randomness.

i.e. a C++ library implementing the Mersenne twister (based on Mersenne primes): Boost Random Number Library - Boost 1.38.0
  boost::mt19937 rng;                 // produces randomness out of thin air
                                      // see pseudo-random number generators
  boost::uniform_int<> six(1,6)       // distribution that maps to 1..6
                                      // see random number distributions
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
           die(rng, six);             // glues randomness with mapping
  int x = die();                      // simulate rolling a die

Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#3
irancplusplus

irancplusplus

    Learning Programmer

  • Members
  • PipPipPip
  • 65 posts
Thanks
but rand is so slow!!
this program tests RandomByt function:

#include <conio.h>

#include <iostream>

using namespace std;

#include <time.h>

#include <Windows.h>

#include <wincrypt.h>


unsigned __int8 RandomByte()

{

	unsigned __int8 ret;

	HCRYPTPROV hProv;

	CryptAcquireContext(&hProv,0,0,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);		

	CryptGenRandom(hProv,1,&ret);

	CryptReleaseContext(hProv,0);

	return ret;

}


unsigned __int8 RandomByte2()

{

	srand(time(0)); //i.e. value = time(NULL) from time.h/ctime.h

    unsigned __int8 number = rand() % 256;

	return number;

}


int main()

{

	double n = 0;

	for(unsigned i = 0; i < 10000; i++)

	{

		unsigned __int8 a = RandomByte(); 

		if(a <= 127)

			n++;

	}

	cout<< n / 10000;	

	_getch();

}

output is always about 0.5
but if one uses RandomByte2 function the output is usually 0 or 1; because srand is too slow.
I wrote this ebook! Will you translate it into English for free!?:confused: PM me!

#4
Alexander

Alexander

    It's Science!

  • Moderators
  • 4,118 posts
  • Location:Vancouver, Eh! Cleverness: 200
srand() must be called once per run, there will be no benefit to branching new sequences every single iteration. You can leave it out of the function and call it at the beginning of main().

rand's speed by itself cannot really be optimised, nor should it be.

10000 iterations of Random2 without srand()
time ./a.out
------------------------------
real    0m0.002s //2ms
user    0m0.000s
sys     0m0.001s
0.5087

Alexander.

Edited by Alexander, 06 December 2011 - 03:43 AM.
test case

Be sure to read the updated FAQ! || Health is achieved through the same 10,000 steps.
If a suggested code/method fails, informing us is less important than telling us why or what errors occurred.

#5
irancplusplus

irancplusplus

    Learning Programmer

  • Members
  • PipPipPip
  • 65 posts
Thanks
now it works:

#include <conio.h>

#include <iostream>

using namespace std;

#include <time.h>


unsigned __int8 RandomByte2()

{	

    unsigned __int8 number = rand() % 256;

	return number;

}


int main()

{

	srand(time(0)); //i.e. value = time(NULL) from time.h/ctime.h

	double n = 0;

	for(unsigned i = 0; i < 10000; i++)

	{

		unsigned __int8 a = RandomByte2(); 

		if(a <= 127)

			n++;

	}

	cout<< n / 10000;	

	_getch();

}


I wrote this ebook! Will you translate it into English for free!?:confused: PM me!




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users