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 |