0

I've been trying to create a password verification using java. The requirements for the password verification should be:

1) The password should be at least six characters long.

2) The password should at least contain one uppercase and lowercase.

3) The password should have at least one digit.

I have done both 1 and 2, but I can't figure out number 3.

I have made a boolean method for checking characters if it has digits. Supposedly, it'll return true if it was able to find a digit, but even if I have entered a password with a digit, it still returns false.

I wonder what's wrong with my code. Hope you guys can help me with this.

package PasswordVerifier;
import java.util.Scanner;
public class PasswordVerifierMain {

public static void main(String[]args){
    Scanner hold = new Scanner(System.in);
    String pass;
    System.out.print("Enter password:");
    pass = hold.nextLine();

    if(isValid(pass) && pass.length() >= 6){

        boolean hasUppercase = pass.equals(pass.toUpperCase());
        boolean hasLowercase = pass.equals(pass.toLowerCase());
        if(!hasUppercase){
            System.out.print("Must have atleast one uppercase letter!");
        }else if(!hasLowercase){
            System.out.print("Must have atleast one lowercase letter!");
        }else{
            System.out.print("Password Successful!");
        }

    }else{
        System.out.print("Invalid Password! Minimum six characters!");
    }

    System.out.println();
    System.out.println(isValid(pass));
}

private static boolean isValid(String pass){
    boolean status = true;
    int i = 0;
    while(status && i < pass.length()){
        if(!Character.isDigit(pass.charAt(i))){
            status = false;
        }
        i++;
    }

    return status;
}

}
5
  • stackoverflow.com/questions/18590901/… Commented Sep 1, 2015 at 11:59
  • As an addition to my answer (I don't want it to grow even more): boolean hasUppercase = pass.equals(pass.toUpperCase()); won't work. Assume a password like aBc123. toUpperCase() would result in ABC123 which is not equal, but the password still contains an upper case character. The same will be true for toLowerCase(). Commented Sep 1, 2015 at 12:18
  • @Thomas - yes, i've tried it and it still didn't work..can you also help me on this one? Commented Sep 2, 2015 at 12:34
  • @Thomas - but I think I have already found the answer..I have just stumble upon this piece of code..I still need to analyze it tho.. boolean hasUppercase = pass.equals(pass.toLowerCase())==false; boolean hasLowercase = pass.equals(pass.toUpperCase())==false; Commented Sep 2, 2015 at 12:50
  • Hmm, yes that should work. However from a performance point of view it might be better to iterate over the characters once and check each of them. Have a look my suggested improvement: with that you'd iterate over the characters only once and would be able to explicity check whether there are upper case characters (you could even count them with a small change) or could implement rules like "Password must have at least 2 of the following: an upper case character, a lower case character, a digit" etc. Commented Sep 2, 2015 at 13:48

2 Answers 2

1

You set status in each iteration, effectively overwriting any true value except for the last character. Besides that you should assume status = false and set it to true if you found a digit. Your code considers any password that contains other characters as well as invalid.

Example:

pass = "1abcde"
status = true

1st iteration: char = 1 -> a digit, so status is not changed 
2nd iteration: char = a -> not a digit, so status will be set to false

loop will break since status is false -> result: not valid

To solve this first assume status = false and when you find a digit set status = true. That way when the password contains a digit it will be considered valid.

Example:

status = false; //assume invalid password
for( char c : pass.toCharArray() ) {
  if( Character.isDigit( c ) ) {
    //found a digit
    status = true;

    //we're done since we found at least one digit
    break;
  }
}
return status;

Your approach could be improved, though:

Iterate over the characters and collect their traits (e.g. upper case, lower case, digit, special character etc.). Then check the number of traits and whether required traits are present.

Example:

enum CharTraits {
  LOWER_CASE,
  UPPER_CASE,
  DIGIT,
  SPECIAL
}

Set<CharTraits> getPasswordTraits( String pw ) {
  Set<CharTraits> traits = new HashSet<>();

  for( char c : pw.toCharArray() ) {
    //better check for index of 0-9 otherwise you allow non-ascii digits as well
    if( Character.isDigit( c ) ) {
      traits.add( DIGIT );
    }
    else if ( Character.isUpperCase( c ) {
      traits.add( UPPER_CASE);
    }
    ... //the rest
  }

  return traits;
}

boolean isValid(String pass){
  Set<CharTraits> traits = getPasswordTraits( String pass )

  //Check for digits (just an example, you could check for more) 
  return traits.contains( DIGIT );

  //if you want to check for 3 out of 4 just do this:
  //return traits.size() >= 3;
}
Sign up to request clarification or add additional context in comments.

Comments

0

If your password is abc123 the method sees the first character, sees it is no digit so it sets "status" to false. Thats why your while would not go into the second round. status has to be true.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.