Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/autofill/password_generator.h" | 5 #include "chrome/browser/autofill/password_generator.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | |
| 7 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 8 | 9 |
| 9 const int kMinChar = 33; // First printable character '!' | 10 const int kMinChar = 33; // First printable character '!' |
| 10 const int kMaxChar = 126; // Last printable character '~' | 11 const int kMaxChar = 126; // Last printable character '~' |
| 11 const int kPasswordLength = 12; | 12 const int kMinUpper = 65; // First upper case letter 'A' |
| 13 const int kMaxUpper = 90; // Last upper case letter 'Z' | |
| 14 const int kMinLower = 97; // First lower case letter 'a' | |
| 15 const int kMaxLower = 122; // Last lower case letter 'z' | |
| 16 const int kMinDigit = 48; // First digit '0' | |
| 17 const int kMaxDigit = 57; // Last digit '9' | |
| 18 // Copy of the other printable symbols from the ascii table since they | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: "ascii" -> "ASCII"
zysxqn
2012/06/01 19:01:32
Done.
| |
| 19 // are disjointed. | |
| 20 const char kOtherSymbols[32] = | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: No need to specify "32", and it would be inco
zysxqn
2012/06/01 19:01:32
Done.
| |
| 21 {'!', '\"', '#', '$', '%', '&', '\'', '(', | |
| 22 ')', '*', '+', ',', '-', '.', '/', ':', | |
| 23 ';', '<', '=', '>', '?', '@', '[', '\\', | |
| 24 ']', '^', '_', '`', '{', '|', '}', '~'}; | |
| 25 const int kMinPasswordLength = 4; | |
| 26 const int kMaxPasswordLength = 20; | |
| 27 | |
| 28 namespace { | |
| 29 | |
| 30 // Classic algorithm to randomly select M elements out of N. | |
| 31 // One description can be found at: "http://stackoverflow.com/questions/48087/se lect-a-random-n-elements-from-listt-in-c-sharp/48089#48089" | |
| 32 int* SelectRandomMFromN(int M, int N) { | |
|
Ilya Sherman
2012/06/01 01:09:55
This should be a void function that takes a std::v
Ilya Sherman
2012/06/01 01:09:55
nit: M and N are completely obfuscated names. Ple
zysxqn
2012/06/01 19:01:32
Done.
zysxqn
2012/06/01 19:01:32
Done.
| |
| 33 DCHECK_GE(N, M); | |
| 34 int* result = new int[M]; | |
| 35 int number_left = N; | |
| 36 int number_needed = M; | |
| 37 for (int i = 0; i < N; ++i) { | |
| 38 if (number_needed == 0) | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: You can just add this to the loop condition.
zysxqn
2012/06/01 19:01:32
Done.
| |
| 39 break; | |
| 40 // we have probability = number_needed / number_left to select | |
| 41 // this position. | |
| 42 int probability = base::RandInt(0, number_left - 1); | |
| 43 if (probability < number_needed) { | |
| 44 result[4 - number_needed] = i; | |
|
Ilya Sherman
2012/06/01 01:09:55
The hardcoded "4" does not make sense now that thi
zysxqn
2012/06/01 19:01:32
Done.
| |
| 45 --number_needed; | |
| 46 } | |
| 47 --number_left; | |
| 48 } | |
| 49 DCHECK_EQ(0, number_needed); | |
| 50 return result; | |
| 51 } | |
| 52 | |
| 53 } // namespace | |
| 12 | 54 |
| 13 namespace autofill { | 55 namespace autofill { |
| 14 | 56 |
| 15 PasswordGenerator::PasswordGenerator() {} | 57 PasswordGenerator::PasswordGenerator() |
| 58 : password_length_(kDefaultPasswordLength) {} | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: If we need to keep this default constructor f
zysxqn
2012/06/01 19:01:32
Prefer to keep this in case some application just
| |
| 59 PasswordGenerator::PasswordGenerator(int max_length) | |
| 60 : password_length_( | |
| 61 max_length >= kMinPasswordLength && max_length <= kMaxPasswordLength ? | |
| 62 max_length : kDefaultPasswordLength) {} | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: Please decompose this logic into a tiny helpe
zysxqn
2012/06/01 19:01:32
Done.
| |
| 16 PasswordGenerator::~PasswordGenerator() {} | 63 PasswordGenerator::~PasswordGenerator() {} |
| 17 | 64 |
| 18 std::string PasswordGenerator::Generate() { | 65 std::string PasswordGenerator::Generate() { |
| 19 std::string ret; | 66 std::string ret; |
| 20 for (int i = 0; i < kPasswordLength; i++) { | 67 // First, randomly select 4 positions to hold one upper case letter, |
| 21 ret.push_back(static_cast<char>(base::RandInt(kMinChar, kMaxChar))); | 68 // one lower case letter, one digit, and one other symbol respectively, |
| 69 // to make sure at least one of each category of characters will be | |
| 70 // included in the password. | |
| 71 int* positions = SelectRandomMFromN(4, password_length_); | |
| 72 | |
| 73 // To enhance the strenght of the password, the upper case letter will be | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: "strenght" -> "strength"
zysxqn
2012/06/01 19:01:32
Done.
| |
| 74 // put at "start"th position, lower case letter will be put at | |
| 75 // "(start+1)%4"th position, digit will be put at "(start+2)%4"th position, | |
| 76 // and other symbol will be put at "(start+3)%4"th position. | |
| 77 int start = base::RandInt(0,3); | |
|
Ilya Sherman
2012/06/01 01:09:55
Please use std::random_shuffle [1] instead.
[1] ht
zysxqn
2012/06/01 19:01:32
Good to know! Done.
| |
| 78 | |
| 79 // Next, generate each character of the password. | |
| 80 for (int i = 0; i < password_length_; ++i) { | |
| 81 if (i == positions[start]) { | |
| 82 // Generate random upper case letter. | |
| 83 ret.push_back(static_cast<char>(base::RandInt(kMinUpper, kMaxUpper))); | |
| 84 } else if (i == positions[(start + 1) % 4]) { | |
| 85 // Generate random lower case letter. | |
| 86 ret.push_back(static_cast<char>(base::RandInt(kMinLower, kMaxLower))); | |
| 87 } else if (i == positions[(start + 2) % 4]) { | |
| 88 // Generate random digit. | |
| 89 ret.push_back(static_cast<char>(base::RandInt(kMinDigit, kMaxDigit))); | |
| 90 } else if (i == positions[(start + 3) % 4]) { | |
| 91 // Generate random other symbol. | |
| 92 ret.push_back(kOtherSymbols[base::RandInt(0, 31)]); | |
|
Ilya Sherman
2012/06/01 01:09:55
nit: Please use the arraysize macro [1] rather tha
zysxqn
2012/06/01 19:01:32
Done.
| |
| 93 } else { | |
| 94 // Generate random character from all categories. | |
| 95 ret.push_back(static_cast<char>(base::RandInt(kMinChar, kMaxChar))); | |
| 96 } | |
| 22 } | 97 } |
| 98 delete positions; | |
|
Ilya Sherman
2012/06/01 01:09:55
Chromium code should almost never need explicit "d
zysxqn
2012/06/01 19:01:32
Done.
| |
| 23 return ret; | 99 return ret; |
| 24 } | 100 } |
| 25 | 101 |
| 26 } // namespace autofill | 102 } // namespace autofill |
| OLD | NEW |