Create random ints with minimum and maximum from Random.NextBytes()

Title pretty much says it all. I know I could use Random.NextInt(), of course, but I want to know if there's a way to turn unbounded random data into bounded without statistical bias. (This means no RandomInt() % (maximum-minimum)) + minimum). Surely there is a method like it, that doesn't introduce bias into the data it outputs?

Jon Skeet
people
quotationmark

If you assume that the bits are randomly distributed, I would suggest:

  • Generate enough bytes to get a number within the range (e.g. 1 byte to get a number in the range 0-100, 2 bytes to get a number in the range 0-30000 etc).
  • Use only enough bits from those bytes to cover the range you need. So for example, if you're generating numbers in the range 0-100, take the bottom 7 bits of the byte you've generated
  • Interpret the bits you've got as a number in the range [0, 2n) where n is the number of bit
  • Check whether the number is in your desired range. It should be at least half the time (on average)
  • If so, use it. If not, repeat the above steps until a number is in the right range.

The use of just the required number of bits is key to making this efficient - you'll throw away up to half the number of bytes you generate, but no more than that, assuming a good distribution. (And if you are generating numbers in a nicely binary range, you won't need to throw anything away.)

Implementation left as an exercise to the reader :)

people

See more on this question at Stackoverflow