cybersecurity · beginner · ~12 min · safe pentest lab

Score a password against a policy struct

Per-character pass over a string, tally character classes, threshold against a policy struct.

Challenge

Your job

Implement:

typedef struct {
    int min_length;
    int require_upper;
    int require_lower;
    int require_digit;
    int require_special;
} pw_policy_t;

int pw_check(const char *pw, const pw_policy_t *p);

Return 0 when the password meets the policy. Return a bitmask of failed requirements otherwise:

Bit Meaning
1 << 0 length too short
1 << 1 missing required uppercase
1 << 2 missing required lowercase
1 << 3 missing required digit
1 << 4 missing required special (non-alphanumeric)

Rules

  • A required class missing → set the corresponding bit. If the policy doesn't require a class, never set its bit even if absent.
  • Length is the byte count of pw (use strlen).
  • pw == NULL → return all 5 bits set (0x1f).

Hints

  1. (concept) One pass over the password is enough to compute has_upper, has_lower, has_digit, has_special.
  2. (direction) isupper(c), islower(c), isdigit(c) from <ctype.h>; "special" = !isalnum(c).
  3. (common bug) char is signed on some platforms — cast to unsigned char before passing to isupper etc.

Why this matters

The defensive cure to brute-force is policy enforcement, not faster crackers.

Input format

A C string + a pointer to a pw_policy_t.

Output format

0 on pass, or a bitmask of failed requirements.

Constraints

No hashing. No online tests. Pure validation.

Starter code

#include <stddef.h>
typedef struct {
    int min_length;
    int require_upper;
    int require_lower;
    int require_digit;
    int require_special;
} pw_policy_t;

int pw_check(const char *pw, const pw_policy_t *p) {
    /* TODO */
    (void)pw; (void)p;
    return 0;
}

Common mistakes

Forgetting the unsigned char cast. Returning 1 for every failure (no caller can tell which). Setting bits for unrequired classes.

Edge cases to handle

NULL pw → 0x1f. Empty string → length bit set. Length exactly equal to min_length → pass.

Complexity

O(n) where n is the password length.

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.