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) {