Home > database >  Java method to check if String includes special characters
Java method to check if String includes special characters

Time:11-21

I'm trying to write a Java code to check if password includes characters, numbers and special characters. Everything fine until the special characters part. The idea is that the index of specialChars and the characters of the Password file are confront and, if there's a match, it would print a positive message, else it would throw an error. But it returns both the positive message and the error. Not sure why.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher; 
import java.util.regex.Pattern;

public class PasswordApp {
    public static void main(String[] args) {

    String filename = "C:\\Users\\gabri\\Desktop\\Generale\\Programmazione\\Java\\Password_Criteria\\Fakepassword.txt";

    File file = new File(filename);
    String Password = null;

    try { 
        BufferedReader br = new BufferedReader(new FileReader(file));

        Password = br.readLine();

        br.close();

    } catch (FileNotFoundException e) { 
        System.out.println("ERROR: File not found: "   filename);
    } catch (IOException e) { 
        System.out.println("ERROR: Could not read the data: "   filename);
    }

    // Password valida: ha almeno un numero, una lettera e un carattere speciale

    try {
        String esitoPositivocarattere = "Carattere incluso.";
        String esitoPositivonumero = "Numero incluso.";
        String esitoPositivospeciale = "Carattere speciale incluso.";
        char[] specialChars = "!@#* -_(%?/{}[].,;:".toCharArray();
        for (int n = 0; n < Password.length(); n  ) {
            if (Password.substring(n).matches(".*[a-z].*")) {
                {
                    System.out.println(esitoPositivocarattere);
                }
            } else {
                throw new MissingCharacterException();
            }
            if (Password.substring(n).matches(".*\\d.*")) {
                System.out.println(esitoPositivonumero);
            } else {
                throw new MissingNumberException();
            }
            for (int i = 0; i < specialChars.length; i  ) {
                if (Password.indexOf(specialChars[i]) > -1) {
                System.out.println(esitoPositivospeciale);
            } else {
                throw new MissingSpecialCharacterException();
            }
        }
        }
    } catch (MissingSpecialCharacterException e) {
        System.out.println("ERRORE: Manca un carattere speciale.");
    } catch (MissingNumberException e) {
        System.out.println("ERRORE: Manca un numero.");
    } catch (MissingCharacterException e) {
        System.out.println("ERRORE: Manca un carattere.");
    }

}
}

class MissingSpecialCharacterException extends Exception { 

}

class MissingNumberException extends Exception {

}

class MissingCharacterException extends Exception {

}

CodePudding user response:

Let's say my password is "X3@" which fulfils the requirements for particular character types.

Now consider your password-checking loop, reformatted to better show the logic:

for (int i = 0; i < specialChars.length; i  ) {
    if (Password.indexOf(specialChars[i]) > -1) {
        System.out.println(esitoPositivospeciale);
    } else {
        throw new MissingSpecialCharacterException();
    }
}

The very first character of specialChars is "!". My password does not contain "!" so we do not print anything. Instead, we throw an error to say there's no special character in the password, obviously wrong.

You code thus requires that a password contains all special characters. You need to rethink that logic.

The smallest change from what you write is something like this (not necessarily the most efficient, I'm just showing the way here):

boolean foundSpecial = false;
for (int i = 0; i < specialChars.length; i  ) {
    if (Password.indexOf(specialChars[i]) > -1) {
        foundSpecial = true;
     }
}
if (foundSpecial) {
    System.out.println(esitoPositivospeciale);
} else {
    throw new MissingSpecialCharacterException();
}

CodePudding user response:

When there's a "less code" way to achieve the problem, you'll have less bugs. Regex is your friend here:

public boolean passwordValid(String password) {
   return password.matches("(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#* _(%?/{}\\[\\].,;:-]).*");
}

See live demo.

Breaking down the regex:

  • (?=.*[a-zA-Z]) is a look ahead that means "a letter appears somewhere later in the input"
  • (?=.*\\d) is a look ahead that means "a digit appears somewhere later in the input"
  • (?=.*[!@#* _(%?/{}\\[\\].,;:-]") is a look ahead that means "a 'special character' appears somewhere later in the input".

Note that the hyphen has been moved to the last place in the character class to avoid it being interpreted as a range.

  • Related