Метод Java для проверки наличия в строке специальных символов

Я пытаюсь написать код Java, чтобы проверить, содержит ли пароль символы, цифры и специальные символы. Все нормально до тех пор, пока не появятся спецсимволы. Идея состоит в том, что индекс specialChars и символы файла Password противопоставляются, и, если есть совпадение, будет напечатано положительное сообщение, иначе будет выдана ошибка. Но он возвращает как положительное сообщение, так и ошибку. Не уверен, почему.

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 {

}

Я думаю, что System.out.println(esitoPositivospeciale); должен быть вне цикла for, иначе вы будете печатать его один раз для каждого символа, пока либо цикл не закончится, либо не будет выбрано исключение.

Dawood ibn Kareem 20.11.2022 22:56

Исправьте отступы, чтобы сделать код более читабельным.

Basil Bourque 21.11.2022 04:27
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
83
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Когда есть способ решить проблему «меньше кода», у вас будет меньше ошибок. Regex - ваш друг здесь:

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

Смотрите живую демонстрацию.

Разрушение регулярного выражения:

  • (?=.*[a-zA-Z]) — это просмотр вперед, что означает «буква появляется где-то позже во вводе»
  • (?=.*\\d) - это просмотр вперед, который означает, что «цифра появляется где-то позже во вводе»
  • (?=.*[!@#*+_(%?/{}\\[\\].,;:-]") — это просмотр вперед, который означает, что «специальный символ» появляется где-то позже во вводе».

Обратите внимание, что дефис был перемещен на последнее место в классе символов, чтобы он не интерпретировался как диапазон.

Я думаю, что там, где ясно, что спрашивающий не совсем понимает поток кода, ответ, который представляет совершенно другой путь, может быть не лучшим подходом. Конечно, у него будет работающий код, но узнает ли он, почему его исходный код не работал?

access violation 20.11.2022 23:47

@accessviolation Я пытаюсь сказать, что этот подход - проблема OP: больше кода означает больше шансов на ошибки.

Bohemian 21.11.2022 00:00

Я собираюсь предложить четыре цента здесь (два мнения). Во-первых, есть два способа интерпретировать такого рода вопросы. Это либо «почему мой код не работает», либо «дайте мне код, который работает». Неясно, какой ответ на самом деле предпочел бы ОП - пытаются ли они понять, что происходит, или просто хотят выполнить свою задачу. Конечно, ответ на вопрос «почему мой код не работает» может оказаться более полезным для других. Но также я серьезно не согласен с утверждением Bohemian о том, что чем больше кода, тем больше шансов для ошибок. Несколько непрозрачное регулярное выражение имеет НАМНОГО больше шансов...

Dawood ibn Kareem 21.11.2022 00:16

... для ошибок, чем простая серия конструкций if, else и for; и если есть ошибки, их будет намного сложнее найти. По крайней мере, подход, предложенный Access Violation, можно легко отлаживать, а также легче понимать и поддерживать.

Dawood ibn Kareem 21.11.2022 00:17

@Bohemian - я категорически не согласен. Это самый ясный код, который, скорее всего, будет содержать наименьшее количество ошибок, а не самый короткий. Особенно для новичка, которым я считаю ОП. Таким образом, я утверждаю, что простой цикл if-else более понятен (для новичка), чем регулярное выражение, использующее несколько экземпляров положительного просмотра нулевой ширины,

access violation 21.11.2022 00:46
Ответ принят как подходящий

Допустим, мой пароль "X3@", который соответствует требованиям для определенных типов символов.

Теперь рассмотрим ваш цикл проверки пароля, переформатированный, чтобы лучше показать логику:

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

Самый первый символ в specialChars — «!». Мой пароль не содержит "!" поэтому мы ничего не печатаем. Вместо этого мы выдаем ошибку о том, что в пароле нет специального символа, что явно неверно.

Таким образом, ваш код требует, чтобы пароль содержал все специальные символы. Вам нужно переосмыслить эту логику.

Наименьшее изменение из того, что вы пишете, выглядит примерно так (не обязательно самое эффективное, я просто показываю путь здесь):

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();
}

Спасибо, нарушение прав доступа! В основном это работало, мне просто нужно было добавить код останова после sysOut, чтобы закрыть цикл.

user13707732 21.11.2022 08:12

Другие вопросы по теме