-3

I am writing a program to accept user name and password using following conditions- username must be min 8 characters. Password must have min 10 characters, 1 lowerCase, 1 upperCase, 1 digit should present in the password. I wrote a method setPassword() following all the conditions. When I try to execute I am getting StringIndexOutOfBound exception. I am unable to understand why I am getting that error:

public void setPassword(String password)
{
    char ch;
    if (password.length() <= 10) {
        for (int i = 0; i <= password.length() - 1; i++) {
            ch = password.charAt(i);
            if (Character.isDigit(ch)) {
                for (int j = 0; j <= password.length() - 1; j++) {
                    char ch1 = password.charAt(j);
                    if (Character.isUpperCase(ch1)) {
                        for(int k = 0; k <= password.length(); k++) {
                            char ch2 = password.charAt(k);
                            if (Character.isLowerCase(ch2)) {
                                this.password = password;
                            }
                        }
                    }
                }
            }
        }
    }
}
Sean Bright
  • 118,630
  • 17
  • 138
  • 146
bharath
  • 3
  • 2
  • 3
    Use`k < password.length()` instead of `k <= password.length`. – M. le Rutte Jun 21 '18 at 18:41
  • Did as you said but getting the same error.D:\java>java Login Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 10 at java.lang.String.charAt(Unknown Source) at Login.setPassword(Login.java:44) at Login.(Login.java:8) at Login.main(Login.java:65) – bharath Jun 21 '18 at 18:45
  • Another mistake that presents in the code: according to your description first line should be `if (password.length() >= 10)` – Isuru Jun 21 '18 at 18:51
  • 1
    use a [regex or several](https://stackoverflow.com/questions/3466850/regular-expression-to-enforce-complex-passwords-matching-3-out-of-4-rules) instead of itterating multiple times thru your string. – mavriksc Jun 21 '18 at 18:55
  • 1
    Seriously: this is **not** how you you should do such validation. Write *one* method per rule to check, and then call these methods one after the other. The code that you put down is basically incomprehensible for human readers. You wrote unreadable code. It doesn't come as surprise that you know need *other* people to explain your own code to you. – GhostCat Jun 21 '18 at 19:22

1 Answers1

1

Ignoring the inefficiencies of this implementation, the following line:

for(int k = 0; k <= password.length(); k++) {

Should either be:

for(int k = 0; k < password.length(); k++) {
//                ^ removed the = from here

Or:

for(int k = 0; k <= password.length() - 1; k++) {
//                                    ^ subtract 1 here

For the following string:

String s = "this-is-a-test";

s.length() is going to return 14. The valid indices of characters in that string are 0 through 13. The idiomatic way of iterating over an array with a for loop is:

for (int i = 0; i < length_of_array; i++)

You've opted to instead use i <= length_of_array - 1 which is effectively the same thing (albeit more verbose), except for your last for loop where you neglect to subtract 1 from the length.

Here is a simplistic method for checking password validity based on the criteria you provided:

public static boolean isPasswordValid(String password)
{
    if (password.length() < 10) {
        return false;
    }

    int lc = 0, uc = 0, digit = 0;

    for (int i = 0; i < password.length(); i++) {
        char c = password.charAt(i);

        if (Character.isLowerCase(c)) {
            lc++;
        } else if (Character.isUpperCase(c)) {
            uc++;
        } else if (Character.isDigit(c)) {
            digit++;
        }
    }

    return lc > 0 && uc > 0 && digit > 0;
}

This will return true if all of the conditions pass, and false otherwise.

Sean Bright
  • 118,630
  • 17
  • 138
  • 146