Fix base::RandGenerator bug (it had non-uniform random distribution). Add test that would have caught bug. Also add a test to verify that our random generators are at least somewhat random.
BUG=84221
TEST=base_unittests --gtest_filter=RandUtilTest.*
Review URL: http://codereview.chromium.org/7080005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87244 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/rand_util.cc b/base/rand_util.cc
index 4140e9a..e556c07 100644
--- a/base/rand_util.cc
+++ b/base/rand_util.cc
@@ -45,7 +45,20 @@
uint64 RandGenerator(uint64 max) {
DCHECK_GT(max, 0ULL);
- return base::RandUint64() % max;
+
+ // We must discard random results above this number, as they would
+ // make the random generator non-uniform (consider e.g. if
+ // MAX_UINT64 was 4 and max was 3, then a result of 1 would be twice
+ // as likely as a result of 0 or 2).
+ uint64 max_acceptable_value =
+ (std::numeric_limits<uint64>::max() / max) * max;
+
+ uint64 value;
+ do {
+ value = base::RandUint64();
+ } while (value >= max_acceptable_value);
+
+ return value % max;
}
void RandBytes(void* output, size_t output_length) {