This source file includes following definitions.
- GetLengthFromHint
- InitializeAlphaNumericCharacters
- GetRandomSelection
- Generate
#include "components/autofill/core/browser/password_generator.h"
#include <algorithm>
#include <vector>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/rand_util.h"
const int kMinUpper = 65;
const int kMaxUpper = 90;
const int kMinLower = 97;
const int kMaxLower = 122;
const int kMinDigit = 48;
const int kMaxDigit = 57;
const char kOtherSymbols[] =
{'!', '\"', '#', '$', '%', '&', '\'', '(',
')', '*', '+', ',', '-', '.', '/', ':',
';', '<', '=', '>', '?', '@', '[', '\\',
']', '^', '_', '`', '{', '|', '}', '~'};
const int kMinPasswordLength = 4;
const int kMaxPasswordLength = 15;
namespace {
int GetLengthFromHint(int max_length, int default_length) {
if (max_length >= kMinPasswordLength && max_length <= kMaxPasswordLength)
return max_length;
else
return default_length;
}
void InitializeAlphaNumericCharacters(std::vector<char>* characters) {
for (int i = kMinDigit; i <= kMaxDigit; ++i)
characters->push_back(static_cast<char>(i));
for (int i = kMinUpper; i <= kMaxUpper; ++i)
characters->push_back(static_cast<char>(i));
for (int i = kMinLower; i <= kMaxLower; ++i)
characters->push_back(static_cast<char>(i));
}
void GetRandomSelection(int num_to_select,
int num_total,
std::vector<int>* selections) {
DCHECK_GE(num_total, num_to_select);
int num_left = num_total;
int num_needed = num_to_select;
for (int i = 0; i < num_total && num_needed > 0; ++i) {
int probability = base::RandInt(0, num_left - 1);
if (probability < num_needed) {
selections->push_back(i);
--num_needed;
}
--num_left;
}
DCHECK_EQ(num_to_select, static_cast<int>(selections->size()));
}
}
namespace autofill {
const int PasswordGenerator::kDefaultPasswordLength = 12;
PasswordGenerator::PasswordGenerator(int max_length)
: password_length_(GetLengthFromHint(max_length, kDefaultPasswordLength)) {}
PasswordGenerator::~PasswordGenerator() {}
std::string PasswordGenerator::Generate() const {
std::string ret;
CR_DEFINE_STATIC_LOCAL(std::vector<char>, alphanumeric_characters, ());
if (alphanumeric_characters.empty())
InitializeAlphaNumericCharacters(&alphanumeric_characters);
std::vector<int> positions;
GetRandomSelection(4, password_length_, &positions);
std::random_shuffle(positions.begin(), positions.end());
for (int i = 0; i < password_length_; ++i) {
if (i == positions[0]) {
ret.push_back(static_cast<char>(base::RandInt(kMinUpper, kMaxUpper)));
} else if (i == positions[1]) {
ret.push_back(static_cast<char>(base::RandInt(kMinLower, kMaxLower)));
} else if (i == positions[2]) {
ret.push_back(static_cast<char>(base::RandInt(kMinDigit, kMaxDigit)));
} else if (i == positions[3]) {
ret.push_back(
kOtherSymbols[base::RandInt(0, arraysize(kOtherSymbols) - 1)]);
} else {
ret.push_back(
alphanumeric_characters.at(
base::RandInt(0, alphanumeric_characters.size() - 1)));
}
}
return ret;
}
}