I've created this C++ random password generator. You can set length, you can enable custom symbols. Then I went to this website: http://www.passwordmeter.com/ and started checking some generated passwords of mine.

Based on the formula here, I've created a simplified version of their grading system, and also created a function for it. Now I can just do password_score(generated_password) and set a limit for the security of my password.

Here are some examples and how my program performs:

###
Password has been copied to clipboard!

###
Password has been copied to clipboard!

###
### $]1V9q (PasswordMeter score: 70%)  Am I doing it right? I know that there's always some room for improvement. I'll take any advice to make it better. Thanks! string password_generator(const int length_of_password = 12, bool enable_symbols = false, bool copy_to_clipboard = false) { vector<char> password; srand (static_cast<unsigned int>(time(nullptr))); //generates lowercase letters for(auto c = 1; c <= length_of_password; c = c + 4) { const auto v1 = rand() % 26; password.push_back(v1 + 'a'); } //generates uppercase letters for(auto g = 3; g <= length_of_password; g = g + 4) { const auto v2 = rand() % 26; password.push_back(v2 + 'A'); } //generates numbers for(auto k = 0; k <= length_of_password; k = k + 2) { const auto v3 = rand() % 10; password.push_back(v3 + '0'); } if(enable_symbols) { //generates symbols for(auto g = 1; g <= length_of_password; g = g + 4) { const auto choice = rand() % 3; if(choice == 0) { const auto v4 = rand() % 14; password.push_back(v4 + '!'); } if(choice == 1) { const auto v5 = rand() % 5; password.push_back(v5 + '['); } if(choice == 2) { const auto v6 = rand() % 4; password.push_back(v6 + '{'); } } } random_device r; shuffle(password.begin(), password.end(), default_random_engine(r())); string returning_password; for(auto i = 0; i < length_of_password; i++) { returning_password.push_back(password[i]); } if(copy_to_clipboard) to_clipboard(returning_password); return returning_password; }  Edit: Here's a main file: (I've just started learning to work with argvs to there might be some mistakes.) (Most of the functions in this program are something I've created -made easier-, they're custom. I strongly recommend checking bottom GitHub link first.) #include <duman.h> using namespace std; int main(const int argc, char* argv[]) { cerr << "###\n"; if(argc > 1 && argc <= 2) { if(string(argv[1]) == "-h") { cerr << "Usage : " << get_file_name(argv[0]) << " -<Password_Length> -<Minimum_Password_Security_Score out of 100>\n"; cerr << "Example: " << get_file_name(argv[0]) << " -12 -80\n\n"; cerr << "Password will be automatically copied to your clipboard!\n"; cerr << "###\n"; return 1; } if(string(argv[1]) == "-v") { cerr << "Version: 1.3.0\n"; cerr << "###\n"; return 2; } if(string(argv[1]) == "-length" || string(argv[1]) == "-l") { cerr << "Try to use the command as:\n"; cerr << get_file_name(argv[0]) << " -8 -98 # for a password that has length of 8 and security score of minimum 98\n"; cerr << "###\n"; return 2; } } if(argc > 2 && argc <= 3) { string raw_argument1 = argv[1]; string raw_argument2 = argv[2]; if(isalpha(raw_argument1[1]) || isalpha(raw_argument2[1])) { cerr << "Invalid parameters! Use -h to see how to use this program.\n"; cerr << "###\n"; return 1; } if(raw_argument1[0] != '-') { cerr << "Did you mean: " << get_file_name(argv[0]) << " -" << argv[1] << " " << raw_argument2 << " # missing dash before an argument!\n"; cerr << "###\n"; return 1; } if(raw_argument2[0] != '-') { cerr << "Did you mean: " << get_file_name(argv[0]) << " " << raw_argument1 << " -" << argv[2] << " # missing dash before an argument!\n"; cerr << "###\n"; return 1; } if(string(argv[1]).empty() || string(argv[2]).empty()) { cerr << "Missing parameters! Use -h to see how to use this program!\n"; cerr << "###\n"; return 1; } raw_argument1.erase(raw_argument1.begin()); raw_argument2.erase(raw_argument2.begin()); const auto first_argument = stoi(raw_argument1); const auto second_argument = stoi(raw_argument2); auto seconds_since_start = 0; const auto start = time(nullptr); auto generated_password = password_generator(first_argument, true, true); while(password_score(generated_password) < second_argument) { if(password_score(generated_password) >= second_argument) { break; } generated_password = password_generator(first_argument, true, true); seconds_since_start += static_cast<int>(difftime(time(nullptr), start)); if(seconds_since_start > 50) { cerr << "Request timed out. Couldn't generate a password with the given parameters.\n"; cerr << "###\n"; return 1; } } cerr << "Generated password strength: " << password_score(generated_password) << "/100\n"; cerr << "Password has been copied to clipboard!\n"; cerr << "###\n"; return 0; } if(argc > 3) { cerr << "Unsupported number of parameters!\n"; return 1; } cerr << "Commands:\n"; cerr << "1. " << get_file_name(argv[0]) << " -length -security_level # Security level is XYZ out of 100\n"; cerr << "2. " << get_file_name(argv[0]) << " -h\n"; cerr << "3. " << get_file_name(argv[0]) << " -v\n"; cerr << "###\n"; }  duman.h is a header file I've created for myself. So, whenever I solve a problem in someway I turn it into a function and save it in that header. You can reach it here: https://github.com/duman/duman.h As I've written in readme, the solutions inside of that file are not the greatest. Pardon for my mistakes already. ## 2 Answers Advice 1 The most important issue with your password generator function is the fact that you keep creating the character vector over and over again. I suggest you roll a class that has that character vector as a field and construct it only once: class password_generator { public: password_generator() { ... // Construct your alphabet. } private: std::vector<char> m_alphabet; };  Advice 2 if(choice == 0) { ... } if(choice == 1) { ... }  Just use switch here: switch (rand() % 2) { case 0: ... case 1: ... case 2: ... }  Advice 3 #include "stdafx.h": In the build settings of Visual Studio, search something like "Use precompiled headers"; set to No. This will remove the need for including that header file. Advice 4 #include <duman.h>: this won't compile on Xcode. The convention is that you use <header> for standard C++ library headers, and "header.h" for your own header files. Advice 5 using namespace std; This one is a poor practice since it abuses your scope with bunch of identifiers/type names. Use instead: #include "funky.hpp" using funky::person; using funky::darth_vader;  Advice 6 In your main driver you output to cerr. This is not what is expected of a command line program. *nix like OS'es has two "handles" one for standard output and one for standard error stream. Your conventional *nix guru will expect normal output to cout and only error stuff to cerr. • 1. Great suggestion! Will do now. 2. Is it better performance wise? 3. That thing was annoying thanks. 4. Oh... didn't know that. I just put the file inside INCLUDE folders of Visual Studio and using it from there. 5. Well... alright. 6. I thought since cerr doesn't have any buffers it could give faster output. Obviously cout is there to "out"put. – Tuğberk Kaan Duman Jan 5 '18 at 20:36 • @TuğberkKaanDuman 2.: Most definitely. When there is a match, other two values will not be tested. Also, I believe that for very large switch statement, the compiler may perform binary search over case values. – coderodde Jan 5 '18 at 20:53 Just a word on password strength: the string '$]1V9q' should not get rated 70% safe. It shouldn't even be rated any percentage safe, because it's a very weak password. Length is the decisive factor in password strength and should weigh far more strongly than other element. Even though the website is originally at fault here for using an inaccurate algorithm, you should avoid making the same mistake!
Also, please use <random>.