How to ask for a password with unique complexities

2019-09-20 16:44发布

问题:

I have to use JOptionPane to get a name, social security number, username, and password. I have the name and social security but I need the other two. The password is really confusing me. It says:

Password should be at least 8 characters in length. They are case sensitive. Our complexity test is that a password should contain at least one number/digit, one capital letter other than the first letter (if the only capital letter is the first letter, that doesn’t pass the complexity test), one special character (non-letter; non-digit). Spaces are not allowed.

I'm at a loss. Here's the rest of my code so far: http://pastebin.com/3UGviCzG

回答1:

How to ask for a password with unique complexities and exceptions in JOptionPane?

Whether you are accepting input from JOptionPane is not an issue here. The logic for the password check is the same even if you get an input from Util.Scanner.

If you do not know where to start, you can always break down the problem into smaller parts. For example. create a helper method for each specific check.

Exmaple:

public static boolean isCorrectLength(String pw){
    //your implementation
}

public static boolean hasSpecialChar(String pw){
    //your implementation    
}

public static boolean isAlphaNumeric(String pw){
    //your implementation    
}

//And so on..

After you solved all the above sub-problems. Use them in your method for validating password:

public static boolean isValidPassword(String pw){
    return (isCorrectLength(pw) && hasSpecialChar(pw) && isAlphaNumeric(pw));
}

Of course, it is possible to create just one method. But if you are "stuck" and not knowing what to do. I believe breaking down your big problem into smaller bits does help.



回答2:

Start by breaking your problem down into manageable chunks.

Password should be at least 8 characters in length.

Well, that's easy...

if (password.length > 7) {
    ...

should contain at least one number/digit

Character.isDigit(char)

one capital letter other than the first letter (if the only capital letter is the first letter, that doesn’t pass the complexity test)

Character.isUpperCase(char)

You'll need to do an additional check when the number of uppercase characters is 1 to determine if it's the first character not...

if (!Character.isUpperCase(password[0])...

one special character (non-letter; non-digit)

Character.isLetterOrDigit(char)

Spaces are not allowed.

Character.isWhitespace(char)

You will need to verify this, as this includes tabs, new lines and a bunch of other white space characters

Now, you just need to put the logic together.

The majority of your work is counting characters and checking to see if you have the correct number or not

Now, because I'm pedantic, I like to start with an interface which defines the core contract...

public interface PasswordValidator {
    public boolean isValid(char[] password);
}

And then generate one or more implementations...

public class ComplexPasswordValidator implements PasswordValidator {

    @Override
    public boolean isValid(char[] password) {
        boolean isValid = false;
        // At least 8 characters long
        if (password.length > 7) {
            int digitCount = 0;
            int capitalCount = 0;
            int nonAlphaDigitCount = 0;
            int whiteSpace = 0;
            for (char c : password) {
                if (Character.isDigit(c)) {
                    digitCount++;
                } else if (Character.isUpperCase(c)) {
                    capitalCount++;
                } else if (Character.isWhitespace(c)) {
                    // This includes tabs, new lines etc...
                    whiteSpace++;
                } else if (!Character.isLetterOrDigit(c)) {
                    nonAlphaDigitCount++;
                }
            }
            // Must have a captial character which is not the first character
            if (capitalCount > 1 || (capitalCount == 1 && !Character.isUpperCase(password[0]))) {
                // Must have a digit, 1 non alpha/digit character and no whitespace
                if (digitCount > 0 && nonAlphaDigitCount == 1 && whiteSpace == 0) {
                    isValid = true;
                }
            }
        }
        return isValid;
    }

}

Now, these don't throw any exceptions, so the only feedback you will get is true or false. It wouldn't be a stretch for you to add exceptions in if your required them.

Then you could simply use it something like...

PasswordValidator pv = new ComplexPasswordValidator();
System.out.println(pv.isValid(new char[]{'T', 'h', 'i', 's', 'I', 's', 'A', 'T', 'e', 's', 't', '_', 'I', 'A', 'm', 'G', 'r', '8'}));
System.out.println(pv.isValid(new char[]{'B', 'a', 'd', '_', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd', '8'}));
System.out.println(pv.isValid(new char[]{'B', 'a', 'd', ' ', 'P', 'a', 's', 's', 'w', 'o', 'r', 'd', '8'}));

You could setup a sequence of methods which took an instance of PasswordValidator and simply pass in whatever validator you wanted

The compiling issue is from the password field....?

Problem #1...

Placing code after the return statement, this makes the code unreacable

public static boolean checkSSN(String social) {

    //...
    return valids;

    //Code to check password
    String password = JOptionPane
            .showInputDialog("Please insert a valid password ");
    boolean valid = isValid(password);
    if (isValid(password)) {
        System.out.println("Valid Password");
    } else {
        System.out.println("Invalid Password");
    }
}

Problem #2...

Failing to define the parameter type...

public boolean isValid(password) { // What type is password?