Check that table evenly divides 256 when generating random string.
This prevents biased modulo arithmetic when selecting a character for a random value from the provided table. BUG=webrtc:5870 Review-Url: https://codereview.webrtc.org/2115793003 Cr-Commit-Position: refs/heads/master@{#13683}
This commit is contained in:
parent
912f46a348
commit
e3eff7c062
@ -207,10 +207,15 @@ std::string CreateRandomString(size_t len) {
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CreateRandomString(size_t len,
|
||||
static bool CreateRandomString(size_t len,
|
||||
const char* table, int table_size,
|
||||
std::string* str) {
|
||||
str->clear();
|
||||
// Avoid biased modulo division below.
|
||||
if (256 % table_size) {
|
||||
LOG(LS_ERROR) << "Table size must divide 256 evenly!";
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<uint8_t[]> bytes(new uint8_t[len]);
|
||||
if (!Rng().Generate(bytes.get(), len)) {
|
||||
LOG(LS_ERROR) << "Failed to generate random string!";
|
||||
|
||||
@ -35,6 +35,8 @@ bool CreateRandomString(size_t length, std::string* str);
|
||||
// Generates a (cryptographically) random string of the given length,
|
||||
// with characters from the given table. Return false if the random
|
||||
// number generator failed.
|
||||
// For ease of implementation, the function requires that the table
|
||||
// size evenly divide 256; otherwise, it returns false.
|
||||
bool CreateRandomString(size_t length, const std::string& table,
|
||||
std::string* str);
|
||||
|
||||
|
||||
@ -55,6 +55,17 @@ TEST_F(RandomTest, TestCreateRandomData) {
|
||||
EXPECT_NE(0, memcmp(random1.data(), random2.data(), kRandomDataLength));
|
||||
}
|
||||
|
||||
TEST_F(RandomTest, TestCreateRandomStringEvenlyDivideTable) {
|
||||
static std::string kUnbiasedTable("01234567");
|
||||
std::string random;
|
||||
EXPECT_TRUE(CreateRandomString(256, kUnbiasedTable, &random));
|
||||
EXPECT_EQ(256U, random.size());
|
||||
|
||||
static std::string kBiasedTable("0123456789");
|
||||
EXPECT_FALSE(CreateRandomString(256, kBiasedTable, &random));
|
||||
EXPECT_EQ(0U, random.size());
|
||||
}
|
||||
|
||||
TEST_F(RandomTest, TestCreateRandomUuid) {
|
||||
std::string random = CreateRandomUuid();
|
||||
EXPECT_EQ(36U, random.size());
|
||||
@ -90,8 +101,8 @@ TEST_F(RandomTest, TestCreateRandomForTest) {
|
||||
std::string str;
|
||||
EXPECT_TRUE(CreateRandomString(16, "a", &str));
|
||||
EXPECT_EQ("aaaaaaaaaaaaaaaa", str);
|
||||
EXPECT_TRUE(CreateRandomString(16, "abc", &str));
|
||||
EXPECT_EQ("acbccaaaabbaacbb", str);
|
||||
EXPECT_TRUE(CreateRandomString(16, "abcd", &str));
|
||||
EXPECT_EQ("dbaaabdaccbcabbd", str);
|
||||
|
||||
// Turn off test mode for other tests.
|
||||
SetRandomTestMode(false);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user