I am developing a program in which I need to generate a random number from an array of bytes which is received from a device which generates random numbers. The problem is; the device sends the random numbers as a stream of bytes, and I need开发者_Python百科 it to generate an integer between a certain value. In other words:
int GenerateRandom(int min, int max, byte[] rndr) {
//Do something with the bytes to make a random integer here between min and max
}
No, I can't use the built-in Random class in .NET, because the program will be used to encrypt secure information, and a pseudo-random-number generator would not be acceptable.
The source code for the java.util.Random
class may help you. I know, I know, it's not C#, but don't downvote just yet. The algorithm is the important bit: given a source of random bits, generate an integer between 0 and n. It's pretty trivial to convert the range [0..n] to [min..max].
I'm sure you can implement the same algorithm in C# in a similar amount of code: around 12 lines, including 2 close braces and 2 lines of input validation.
EDIT: The nextInt(int n)
function is the one you want to look at.
EDIT2: Alternatively, you could use a RNGCryptoServiceProvider
seeded with your high-quality random bits. That may be secure enough for your purposes, especially if you can reseed every so often with new, high-quality randomness.
Interestingly, the msdn website does not work correctly with Chrome on Linux. Who'd have thunk?
If you need a cryptograhically strong random number then the .NET framework has the RNGCryptoServiceProvider class for this purpose.
GetBytes() fills an array of bytes with a cryptographically strong sequence of random values.
If this array of bytes already contains a random number, you can use it as a sample value. In this example I am using the first 4 bytes, you can modify this for whatever word size is applicable and make it rotate words.
static int GenerateRandom(int min, int max, byte[] rndr)
{
int isamp = (int)(((uint)rndr[3] << 24) | ((uint)rndr[2] << 16) | ((uint)rndr[1] << 8) | ((uint)rndr[0]));
if (isamp < 0)
isamp += int.MaxValue;
double samp = isamp * 4.6566128752457969E-10;
return (int)(samp * (max - min)) + min;
}
精彩评论