package net.techreadiness.util; /** * PasswordComplexityValidator determines how complex a password is based on the following requirements: * * Standard Password rules: * <ul> * <li>Complexity 0 = none of the rules below need to be met to be considered a valid password</li> * <li>Complexity 1 = one of the rules below need to be met to be considered a valid password</li> * <li>Complexity 2 = two of the rules below need to be met to be considered a valid password</li> * <li>Complexity 3 = three of the rules below need to be met to be considered a valid password</li> * </ul> * * Uppercase: 1 Lowercase: 1 Number: 1 Special Chars: 1 Min Length: 8 Max Length: 32 Special Chars: * ~`!@#$%^&*()_-+=}{[]|\:;<,>.?/ * */ public class PasswordComplexityEvaluator { // For character determinations private static final int CHAR_LOWER_A = 'a'; private static final int CHAR_LOWER_Z = 'z'; private static final int CHAR_UPPER_A = 'A'; private static final int CHAR_UPPER_Z = 'Z'; private static final int CHAR_NUMERIC_ZERO = '0'; private static final int CHAR_NUMERIC_NINE = '9'; // Since the alpha and numeric checks handle the [a-zA-Z0-9] case in // earlier if statement checks, we can then assume the surrounding // characters // within the range of the special char lower and upper values are in fact // special characters. If it extends past the range, then it's no longer a // symbol. private static final int CHAR_LOWER_SPECIAL_CHAR = ' '; private static final int CHAR_UPPER_SPECIAL_CHAR = '~'; // Configurable variables private static int minPasswordLength = 8; private static int maxPasswordLength = 32; private static int minLowerAlphaChars = 1; private static int minUpperAlphaChars = 1; private static int minSpecialChars = 1; private static int minNumericalChars = 1; public static int getPasswordComplexity(String password) throws IllegalArgumentException { int complexity = 0; if (password == null || password.isEmpty()) { return 0; } int passwordLen = password.length(); if (passwordLen > maxPasswordLength) { throw new IllegalArgumentException("Maximum password length is required to be less than or equal to: " + maxPasswordLength); } if (passwordLen >= minPasswordLength) { complexity++; } int alphaLowerCharsCount = 0; int alphaUpperCharsCount = 0; int numericCharsCount = 0; int specialCharsCount = 0; // Count the characters char passwordChar; for (int i = 0; i < passwordLen; i++) { passwordChar = password.charAt(i); if (passwordChar >= CHAR_LOWER_A && passwordChar <= CHAR_LOWER_Z) { alphaLowerCharsCount++; } else if (passwordChar >= CHAR_UPPER_A && passwordChar <= CHAR_UPPER_Z) { alphaUpperCharsCount++; } else if (passwordChar >= CHAR_NUMERIC_ZERO && passwordChar <= CHAR_NUMERIC_NINE) { numericCharsCount++; } else if (passwordChar >= CHAR_LOWER_SPECIAL_CHAR && passwordChar <= CHAR_UPPER_SPECIAL_CHAR) { specialCharsCount++; } } if (alphaLowerCharsCount >= minLowerAlphaChars) { complexity++; } if (alphaUpperCharsCount >= minUpperAlphaChars) { complexity++; } if (numericCharsCount >= minNumericalChars) { complexity++; } if (specialCharsCount >= minSpecialChars) { complexity++; } return complexity; } }