In some implementations, rand() did not provide good randomness on its low-order bits, so the module operator would not provide very random results. If you find this to be the case, you can try this instead:
int uniform_distribution(int rangeLow, int rangeHigh) { double myRand = rand()/(1.0 + RAND_MAX); int range = rangeHigh - rangeLow + 1; int myRand_scaled = (myRand * range) + rangeLow; return myRand_scaled; }
Using rand() , this method will result in an offset, as Lior notes. But, the technique is great if you can find a uniform number generator to calculate myRand . One possible candidate would be drand48() . This will significantly reduce the amount of bias towards something that would be very difficult to detect.
However, if you need something cryptographically secure, you should use the algorithm described in Lior's answer, assuming your rand() itself is cryptographically secure (probably not by default, so you need to find it). The following is a simplified implementation of what Lior described. Instead of counting the bits, we assume that the range is within the range of RAND_MAX , and calculate the appropriate number. In the worst case, the algorithm terminates the call of the random number generator twice on average by request for a number in the range.
int uniform_distribution_secure(int rangeLow, int rangeHigh) { int range = rangeHigh - rangeLow + 1; int secureMax = RAND_MAX - RAND_MAX % range; int x; do x = secure_rand(); while (x >= secureMax); return rangeLow + x / (secureMax / range); }
jxh Jul 25 2018-12-12T00: 00Z
source share