我正在编写密码验证程序,并且在检查特殊字符的or语句中存在一些问题。我不确定它有什么问题,程序的其余部分似乎运行正常,但输入符合条件的密码,例如P @ ndas123 $%,只会导致无限循环。
我认为这个问题与我对!pass.contains("")部分的重要声明有关。如果这是对的,有人可以帮助我理解为什么声明不正确吗?
import java.util.Scanner;
public class DylanJacksonProg5 {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
boolean valid;
valid = true;
do {
//Password rules declared to user
System.out.println("Password Verifier");
System.out.println("");
System.out.println("Enter a password that meets the following rules: ");
System.out.println(" Is at least 8 characters long");
System.out.println(" Contains at least 1 lower letter character");
System.out.println(" Contains at least 1 upper letter character");
System.out.println(" Contains at least 1 numeric digit");
System.out.println(" Contains at least 1 special character of the following set: !@#$%^&*");
System.out.println(" Does not contain the word 'and' or the word 'the'");
//Gathering password from user
System.out.println("Enter your password: ");
String pass;
pass = user_input.next();
//Validating password to rules
if (pass.length() < 8) {
int shortlen;
shortlen = 8 - pass.length();
System.out.println("Password is too short. Please add " + shortlen + " characters");
valid = false;
} else
System.out.println("Password length is acceptable.");
//Check for character cases
boolean hasUppercase = !pass.equals(pass.toLowerCase());
boolean hasLowercase = !pass.equals(pass.toUpperCase());
if (!hasUppercase) {
System.out.println("Must have an uppercase Character");
valid = false;
}
if (!hasLowercase) {
System.out.println("Must have a lowercase Character");
valid = false;
}
if (hasUppercase) {
System.out.println("Has an upper case character");
}
if (hasLowercase) {
System.out.println("Has a lowercase Character");
}
//Check for digit
for (int i = 0; i < pass.length(); i++) {
char x = pass.charAt(i);
if (!Character.isDigit(x)) {
valid = false;
}
}
//check for special character
if (!pass.contains("!") || !pass.contains("@") || !pass.contains("#") || !pass.contains("$") ||
!pass.contains("%") || !pass.contains("^") || !pass.contains("&") || !pass.contains("*"))
{
valid = false;
System.out.println("Password requires a special character from the following: !@#$%^&*");
}
// check for 'and'
if (pass.contains("and")) {
valid = false;
System.out.println("Cannot contain 'and'");
}
//check for 'the'
if (pass.contains("the")) {
valid = false;
System.out.println("Cannot contain 'the'");
}
System.out.println("");
}
while (!valid);
}
}
答案 0 :(得分:1)
我会直接告诉你一个问题。
由于您在验证循环之前将valid
设置为true,并且仅在循环中将其设置为false,因此在第一次尝试时输入无效密码将导致循环从不离开。
将valid
设置为true应该是在循环中完成的第一件事。
除此之外,您的检查每个都单独应用于输入字符串中的每个字符,这种情况是不可能的。例如,您检查整个字符串是否等于其小写变体,然后检查它是否也等于其大写变体。
这意味着任何包含字母的字符串都将被视为无效,因为xyZZy
不能同时与xyzzy
和XYZZY
同等。
做一些像(伪代码,并减少几个条件只是为了显示方法)会更正确:
do:
hasLowercase = false
hasUpperCase = false
hasNumeric = false
isLongEnough = false
get string from user
if len(string) >= 8:
isLongEnough = true
for each character in string:
if character is lowercase:
hasLowerCase = true
if character is uppercase:
hasUpperCase = true
if character is numeric:
hasNumeric = true
isValid = hasLowerCase && hasUpperCase && hasNumeric && isLongEnough
until isValid
这将检查每个单独的字符,以便其中任何(而不是要求所有)将条件标记为true。
答案 1 :(得分:0)
您的代码存在多个问题,这些问题彼此无关:
valid
设置为true
,这意味着如果您输入1个错误密码,valid
将始终保持false
,这意味着无论您之后输入多少正确的密码,循环都将无限重复。换句话说:只有在您第一次尝试输入正确的密码时,程序才会停止。大布尔表达式不检查密码是否包含任何字符,而是检查密码是否包含所有字符。绘制真相表或应用DeMorgan的法律,你会看到:
!p.c("!") || !p.c("@") || !p.c("#") || !p.c("$") || !p.c("%") || !p.c("^") || !p.c("&") || !p.c("*")
// is the same per DeMorgan's Laws as
!(p.c("!") && p.c("@") && p.c("#") && p.c("$") && p.c("%") && p.c("^") && p.c("&") && p.c("*"))
很明显#2和#3相互矛盾,因此根本无法输入有效密码,因此即使你修复了#1,仍然无法退出循环。
答案 2 :(得分:0)
如果您没有密码中的所有特殊字符,则OR运算符会发生冲突,因为在条件语句中,如果您有“!”但不是“@”,它仍然会导致错误值。
您可以做的是分别检查每个特殊字符。
答案 3 :(得分:0)
很抱歉没有解释,但这是你的特殊字符检查块中的否定声明。通常使用!条件有效,但它没有在我使用的这个在线IDE上。不确定为什么。
此代码可以使用:
//check for special character
if (pass.contains("!") || pass.contains("@") || pass.contains("#") || pass.contains("$") ||
pass.contains("%") || pass.contains("^") || pass.contains("&") || pass.contains("*"))
{
valid = true;
System.out.println("Password requires a special character from the following: !@#$%^&*");
}
else
{
valid = false;
}
答案 4 :(得分:0)
以下是OR运算符的工作原理:
if( condition1 || condition2 || condition3 || condition4)
{
// .....your code;
}
如果condition1为真,则不检查剩余条件,程序将移动到IF块内。但是,如果Condition1为false,则检查condition2。如果这是真的,则不检查剩余条件否则(如果它是假的)将检查condition3。依此类推。但是,正如其他人已经提到的那样,你的代码存在的问题多于OR运算符。
例如,对于password = P @ ndas123 $%,它不包含“!”,所以!pass.contain(“!”)将给出true,有效将被设置为false,从而导致无限循环。
答案 5 :(得分:0)
您的代码存在3个问题:
do {
valid = true;
...
降低&amp;大写检查应以不同方式进行,例如:
boolean hasUppercase = false;
boolean hasLowercase = false;
for (int i = 0; i < pass.length(); i++){
if (Character.isUpperCase(pass.charAt(i))){
hasUppercase = true;
}
if (Character.isLowerCase(pass.charAt(i))){
hasLowercase = true;
}
}
您的特殊字符检查不正确,您可以使用以下代码:
if (!(pass.contains("!") || pass.contains("@") || pass.contains("#") || pass.contains("$") || pass.contains("%") || pass.contains("^") || pass.contains("&") || pass.contains("*"))){
valid = false;
}
boolean isDigit = false;
for (int i = 0; i < pass.length(); i++) {
char x = pass.charAt(i);
if (Character.isDigit(x)) {
//valid = false;
isDigit = true;
break;
}
}
if (!isDigit)
valid = false;