CppSecurity  1.1.1.0
C++ Security Library
password_generator.cpp
Go to the documentation of this file.
1 
10 
11 #include "errors/exceptions.h"
12 #include "memory/memory.h"
13 #include "utility/countof.h"
14 
15 #include <cassert>
16 
17 namespace CppSecurity {
18 
20  : _length(length), _flags(flags)
21 {
22  assert((length >= 6) && "Password should be at least 6 bytes!");
23  if (length < 6)
24  throwex CppCommon::SecurityException("Invalid password length!");
25 }
26 
28 {
29  char lower[] = "abcdefghijklmnopqrstuvwxyz";
30  char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
31  char digits[] = "012345678901234567890123456789";
32  char symbols[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
33 
34  std::string cache;
35  if ((flags() & PasswordFlags::lower) != 0)
36  cache += lower;
37  if ((flags() & PasswordFlags::upper) != 0)
38  cache += upper;
39  if ((flags() & PasswordFlags::digits) != 0)
40  cache += digits;
41  if ((flags() & PasswordFlags::symbols) != 0)
42  cache += symbols;
43 
44  size_t offset = 0;
45  std::password result(length(), 0);
46  CppCommon::Memory::CryptoFill(result.data(), result.size());
47 
48  if ((flags() & PasswordFlags::lower) != 0)
49  result[offset] = lower[result[offset] % (CppCommon::countof(lower) - 1)], ++offset;
50  if ((flags() & PasswordFlags::upper) != 0)
51  result[offset] = upper[result[offset] % (CppCommon::countof(upper) - 1)], ++offset;
52  if ((flags() & PasswordFlags::digits) != 0)
53  result[offset] = digits[result[offset] % (CppCommon::countof(digits) - 1)], ++offset;
54  if ((flags() & PasswordFlags::symbols) != 0)
55  result[offset] = symbols[result[offset] % (CppCommon::countof(symbols) - 1)], ++offset;
56 
57  for (size_t i = offset; i < length(); ++i)
58  result[i] = cache[result[i] % cache.size()];
59 
60  return result;
61 }
62 
63 bool PasswordGenerator::Validate(std::string_view password) const
64 {
65  // Validate password length requirement
66  if (password.size() < length())
67  return false;
68 
69  // Collect password flags requirements
70  bool lower = false;
71  bool upper = false;
72  bool digits = false;
73  bool symbols = false;
74  for (size_t i = 0; i < password.size(); ++i)
75  {
76  if ((password[i] >= 'a') && (password[i] <= 'z'))
77  lower = true;
78  else if ((password[i] >= 'A') && (password[i] <= 'Z'))
79  upper = true;
80  else if ((password[i] >= '0') && (password[i] <= '9'))
81  digits = true;
82  else if ((password[i] == '!') || (password[i] == '"') || (password[i] == '#') || (password[i] == '$') || (password[i] == '%') ||
83  (password[i] == '&') || (password[i] == '\'') || (password[i] == '(') || (password[i] == ')') || (password[i] == '*') ||
84  (password[i] == '+') ||(password[i] == ',') || (password[i] == '-') || (password[i] == '.') || (password[i] == '/') ||
85  (password[i] == ':') || (password[i] == ';') || (password[i] == '<') || (password[i] == '=') || (password[i] == '>') ||
86  (password[i] == '?') || (password[i] == '@') || (password[i] == '[') || (password[i] == '\\') || (password[i] == ']') ||
87  (password[i] == '^') || (password[i] == '_') || (password[i] == '`') || (password[i] == '{') || (password[i] == '|') ||
88  (password[i] == '}') || (password[i] == '~'))
89  symbols = true;
90  else
91  return false;
92  }
93 
94  // Validate password flags requirements
95  if (!lower && ((flags() & PasswordFlags::lower) != 0))
96  return false;
97  if (!upper && ((flags() & PasswordFlags::upper) != 0))
98  return false;
99  if (!digits && ((flags() & PasswordFlags::digits) != 0))
100  return false;
101  if (!symbols && ((flags() & PasswordFlags::symbols) != 0))
102  return false;
103 
104  return true;
105 }
106 
107 } // namespace CppSecurity
virtual std::password Generate() const
Generate the strong password with the current password requirements.
size_t length() const noexcept
Get the password length.
PasswordGenerator(size_t length=12, PasswordFlags flags=PasswordFlags::lower|PasswordFlags::upper|PasswordFlags::digits)
Initialize password generator with required parameters.
virtual bool Validate(std::string_view password) const
Validate the given password with the current password requirements.
PasswordFlags flags() const noexcept
Get the password flags.
Password string.
Definition: password.h:53
PasswordFlags
Password flags.
@ upper
Password must contain alphabet characters in upper case (A-Z)
@ symbols
Password must contain punctuation symbols (!"#$%&'()*+,-./:;<=>?@[]^_`{|}~)
@ lower
Password must contain alphabet characters in lower case (a-z)
@ digits
Password must contain digits (0-9)
Password generator definition.