What is the best way to check the strength of a password?

What is the best way of ensuring that a user supplied password is a strong password in a registration or change password form?

One idea I had (in python)

def validate_password(passwd):
    conditions_met = 0
    conditions_total = 3
    if len(passwd) >= 6: 
        if passwd.lower() != passwd: conditions_met += 1
        if len([x for x in passwd if x.isdigit()]) > 0: conditions_met += 1
        if len([x for x in passwd if not x.isalnum()]) > 0: conditions_met += 1
    result = False
    print conditions_met
    if conditions_met >= 2: result = True
    return result

Depending on the language, I usually use regular expressions to check if it has:

  • At least one uppercase and one lowercase letter
  • At least one number
  • At least one special character
  • A length of at least six characters

You can require all of the above, or use a strength meter type of script. For my strength meter, if the password has the right length, it is evaluated as follows:

  • One condition met: weak password
  • Two conditions met: medium password
  • All conditions met: strong password

You can adjust the above to meet your needs.


The object-oriented approach would be a set of rules. Assign a weight to each rule and iterate through them. In psuedo-code:

abstract class Rule {

    float weight;

    float calculateScore( string password );

}

Calculating the total score:

float getPasswordStrength( string password ) {     

    float totalWeight = 0.0f;
    float totalScore  = 0.0f;

    foreach ( rule in rules ) {

       totalWeight += weight;
       totalScore  += rule.calculateScore( password ) * rule.weight;

    }

    return (totalScore / totalWeight) / rules.count;

}

An example rule algorithm, based on number of character classes present:

float calculateScore( string password ) {

    float score = 0.0f;

    // NUMBER_CLASS is a constant char array { '0', '1', '2', ... }
    if ( password.contains( NUMBER_CLASS ) )
        score += 1.0f;

    if ( password.contains( UPPERCASE_CLASS ) )
        score += 1.0f;

    if ( password.contains( LOWERCASE_CLASS ) )
        score += 1.0f;

    // Sub rule as private method
    if ( containsPunctuation( password ) )
        score += 1.0f;

    return score / 4.0f;

}