Kelick Tech Hub

Build, learn & keep up — tech, Linux & sports news included.

C++ Password Strength Checker Project

Beginner•2–3 hours•strings, character checks, scoring

Type a password and get an instant strength rating with reasons.

Share on X

What you will build

Paste in a password and the checker scores it — length, mixed case, digits, symbols — then explains what's missing. It teaches systematic string analysis, and the scoring-rules design is your first taste of building a small rule engine.

What you will learn

Feature checklist

Starter code

#include <iostream>
#include <string>
#include <cctype>

int score(const std::string& pw, bool& up, bool& low,
          bool& dig, bool& sym) {
    up = low = dig = sym = false;
    for (unsigned char c : pw) {
        if (std::isupper(c)) up = true;
        else if (std::islower(c)) low = true;
        else if (std::isdigit(c)) dig = true;
        else sym = true;
    }
    int s = 0;
    if (pw.size() >= 8)  ++s;
    if (pw.size() >= 12) ++s;
    if (up) ++s; if (low) ++s; if (dig) ++s; if (sym) ++s;
    return s;  // 0-6
}

int main() {
    std::string pw;
    std::cout << "Password: ";
    std::getline(std::cin, pw);
    bool u, l, d, s;
    int sc = score(pw, u, l, d, s);
    std::cout << "Score: " << sc << "/6 -> "
              << (sc <= 2 ? "Weak" : sc <= 4 ? "Fair" : "Strong") << "\n";
    if (!u) std::cout << " - add an uppercase letter\n";
    if (!d) std::cout << " - add a digit\n";
    if (!s) std::cout << " - add a symbol like ! or #\n";
}

Full walkthrough

Step 1: Define what 'strong' means as countable checks

The starter's score() function runs a battery of yes/no tests on the string: length at least 8, length at least 12, contains a lowercase letter, an uppercase letter, a digit, and a symbol — one point each, 6 maximum. Turning 'strong' into six concrete questions is the design move; the rest of the program is just asking them.

Step 2: Classify characters with <cctype>

Loop over the string once, setting flags with std::islower, std::isupper, std::isdigit from <cctype>, and treat 'not alphanumeric and not space' as a symbol. One pass, four flags. Cast each char to unsigned char before calling the cctype functions — passing a negative char value is undefined behaviour that bites on non-ASCII input.

for (char ch : pw) {
    unsigned char u = static_cast<unsigned char>(ch);
    if (std::islower(u)) hasLower = true;
    else if (std::isupper(u)) hasUpper = true;
    else if (std::isdigit(u)) hasDigit = true;
    else if (!std::isspace(u)) hasSymbol = true;
}

Step 3: Map the score onto a verdict

0–2 points is Weak, 3–4 is Fair, 5 is Strong, 6 is Excellent. Keep the thresholds in one place so the report and the verdict can never disagree about what a 4 means.

Step 4: Report exactly which checks failed

The checklist demands specifics, not just a grade: print a line per failed test ('✗ no symbol', '✗ under 12 characters'). This is why score() should expose the individual results, not only the total — a struct of bools or a bitmask beats a bare int the moment the report needs detail.

Step 5: Flag the embarrassingly common patterns

Check the lowercased password against a small built-in list ('password', '123456', 'qwerty', 'letmein') and for obvious sequences like '1234' or 'abcd' inside it. A hit caps the verdict at Weak no matter how many points it scored — 'Password1!' passes every composition rule and is still a terrible password, and your checker should say so.

Step 6: Never echo the password back

Read the password, analyse it, report on it — but do not print it in the results. The starter's checklist says 'never stores or prints the password back unnecessarily', which is a real security habit, not decoration: checkers that log passwords create the very leaks they exist to prevent.

Step 7: Test with a ladder of passwords

Run 'abc' (Weak), 'sunshine' (long but one class, plus a dictionary word), 'Sunshine7' (Fair/Strong boundary), and 'Tr7!falcon99' (12 characters, all four classes — Excellent). If 'Password1!' does not get flagged as common, your pattern check is not wired in.

Common mistakes

Compile and run

g++ -std=c++17 -o password_checker password_checker.cpp

Sample run

$ ./password_checker
Enter a password to check:
> sunshine
Strength: Weak (2/6)
  ✓ at least 8 characters
  ✓ has a lowercase letter
  ✗ under 12 characters
  ✗ no uppercase letter
  ✗ no digit
  ✗ no symbol

Enter a password to check:
> Tr7!falcon99
Strength: Excellent (6/6)
  ✓ at least 8 characters
  ✓ at least 12 characters
  ✓ lowercase, uppercase, digit and symbol all present

Enter a password to check:
> Password1!
Strength: Weak — this is one of the most common passwords in the world.

Try it in your browser

This project has a browser demo in the classic site. The demo is a browser re-implementation of the same logic, not the compiled C++ program: Type a password and watch the strength meter react. Nothing you type leaves this page.

Open the browser demo in the classic site →

Related Beginner projects

← All 60 projects · Classic site (Learn & Sandbox)

Download Fake GPS