I am writing something that reads bytes (just List<int> ) from a random number source, which is very slow. For this and my personal requirements, I want to get as few bytes from the source as possible .
Now I'm trying to implement a method whose signatures look like this:
int getRandomInteger(int min, int max)
I have two theories on how I can get bytes from my random source and convert them to an integer.
Approach No. 1 naive. Extract (max - min) / 256 number of bytes and add them. It works, but it collects a lot of bytes from the source of the slow random number generators that I have. For example, if I want to get a random integer from a million to zero, it will extract almost 4,000 bytes ... this is unacceptable.
Approach # 2 sounds perfect to me, but I can't come up with an algorithm. it looks like this:
Take min: 0, max: 1000 as an example.
- Compute
ceil(rangeSize / 256) , which in this case is equal to ceil(rangeSize / 256) ceil(1000 / 256) = 4 . Now select one (1) byte from the source. - Scale this one byte from the range 0-255 to the range 0-3 (or 1-4) and determine which group we are using. For instance. if the byte was 250, we would select the fourth group (which represents the last 250 numbers, 750-1000 in our range).
- Now select a different byte and a scale from 0-255 to 0-250 and let this determine the position within the group that we have. Therefore, if this second byte is, for example, 120, then our final integer is
750 + 120 = 870 .
In this scenario, we only needed 2 bytes. However, it is much more complicated if our range is 0-1000000, we need several "groups".
How do I implement something like this? I am fine with Java / C # / JavaScript code or pseudo code.
I would also like to save the result without losing entropy / randomness. So, I'm a little concerned about integer scaling.
Tower source share