【问题标题】:Password input rules密码输入规则
【发布时间】:2017-05-17 18:52:28
【问题描述】:
import java.util.Scanner;
public class Exercise6_18 {
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.print("Password rules:\n"
            + "Password must have at least eight characters\n"
            + "Password must consist of only letters and digits\n"
            + "Password must contain at least two digits\n"
            + "Enter a password:");
    String pWT = sc.next();
    passWordIsValid(pWT);
    }
    public static void passWordIsValid (String password) {
        boolean passWordIsValid;

        if (password.length() < 8) {
            passWordIsValid = false;
            }
        else if (password.indexOf(0) == -1 && password.indexOf(1) == -1
                && password.indexOf(2) == -1 && password.indexOf(3) == -1
                && password.indexOf(4) == -1 && password.indexOf(5) == -1
                && password.indexOf(6) == -1 && password.indexOf(7) == -1
                && password.indexOf(8) == -1 && password.indexOf(9) == -1) {
                passWordIsValid = false;
        }
        else 
            passWordIsValid = true;     

        if (passWordIsValid == true) 
            System.out.print("Password is valid");
        else if (passWordIsValid == false) 
            System.out.println("Password is invalid");      
    }   
}

我正在尝试编写一个程序,提示用户输入至少 8 个字符长、至少包含两位数字且仅由字母和数字组成的密码,但是当我输入时:password12 它说密码无效.附言我知道我没有在方法中添加至少两位数的要求。

【问题讨论】:

  • 试试password.indexOf("0") == -1 ....。您要查找字符串 0,而不是代码点 0
  • 非常感谢,我不敢相信我没有注意到这一点!
  • 另外,尝试手动遍历算法,您会在 passwordIsValid() 的第一个 else 块中发现逻辑错误。如果您的密码包含“1”,则 index("1 ") 将返回一个正数,因此测试将是错误的。
  • 假设密码 > 8 个字符,例如 ABCDEFGHIJKLMNOP12ABCDEFGHIJKLMNOP12#。考虑使用循环来检查每个字符。

标签: java passwords


【解决方案1】:
...else if (password.indexOf(0) == -1 && password.indexOf(1) == -1
            && password.indexOf(2) == -1 && password.indexOf(3) == -1
            && password.indexOf(4) == -1 && password.indexOf(5) == -1
            && password.indexOf(6) == -1 && password.indexOf(7) == -1
            && password.indexOf(8) == -1 && password.indexOf(9) == -1) {
            passWordIsValid = false;
    }...

你想用这段代码实现什么?这根本没有任何意义。您可能希望循环遍历字符串的每个字符,而不是计算每个字符(如果它是数字)(并且一旦计数 >=2,您就可以“中断;”退出循环)。

另外:不要将密码保存在字符串中……它们会在字符串池中停留很长一段时间,并且可以被恶意程序从内存中读取。您可以改用 char[]。

【讨论】:

  • 不是一个很好的答案,但至少比所有其他人都朝着更好的方向发展......
【解决方案2】:

如果你不想使用Regex,你可以使用一个简单的for loopif statement,你可以这样做:

import java.util.Scanner;

public class PromptPassword {

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.print("Password rules:\n"
                            + "Password must have at least eight characters\n"
                            + "Password must consist of only letters and digits\n"
                            + "Password must contain at least two digits\n"
                            + "Enter a password:");
        String pWT = sc.nextLine(); //read the entire line
        passWordIsValid(pWT.trim()); // to remove leading spaces (if any)
    }   
    public static void passWordIsValid (String password) {
        boolean passWordIsValid = true;
        int noOfDigits =0;


        if (password.length() > 8) { // if it's less than 8 chars -> no need to continue
            for(char c : password.toCharArray()){
                if(Character.isDigit(c)){ // if it's a digit, increment
                    noOfDigits++;
                }
                else if(!Character.isAlphabetic(c)){ // if it's not a digit nor alphapet
                    passWordIsValid = false;
                    break;
                }
            }
        }

         if (passWordIsValid && noOfDigits>=2){
             System.out.print("Password is valid");
         }
         else{
             System.out.println("Password is invalid"); 
         }

    }
}

测试

Enter a password: abcd12     ->  Password is invalid (less than 8)
Enter a password: abcde@123  ->  Password is invalid (contains special char)
Enter a password: abcdefghi1 ->  Password is invalid (less than 2 digits)
Enter a password: abcdefg12  ->  Password is valid (9 in length and contains 2 digits and no special chars)

【讨论】:

    【解决方案3】:

    您的算法不会检查是否至少有两位数字,也不会检查其中是否只有可打印的字符和数字。而不是检查 indexOf() 您需要遍历所有字符并计算数字的数量,并确保每个字符都是数字或字母字符,跟踪数字的数字。

    【讨论】:

      【解决方案4】:

      使用正则表达式验证密码。正向 Lookahead 在验证字符串方面做得非常好。

      java 中的示例

       public static void main(String[] args) {
          String passwd = "aaZZa44@"; 
          String pattern = "^(?=.*[0-9].*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}$";
        System.out.println(passwd.matches(pattern));
      

      }

      (?=.*[0-9].*[0-9]) at least 2 digits.
      (?=.*[a-z]) lower case a-z
      (?=.*[A-Z]) upper case A-Z
      {8,} 8 digit in length
      

      【讨论】:

      • 谢谢,这比我想象的要好得多
      • 欢迎您使用该正则表达式,因此请包含不同的修饰符。
      • 所以我在 if 语句中尝试了这个,它可以工作,除非我只使用小写字符。有没有办法解决这个问题?
      • 是的,如果你只想要小写密码,你可以取出 (?=.*[A-Z]) 并且应该以 2 位小写字母和至少 8 个字符长传递
      • 我也可以推荐你到这个网站,在那里你可以测试这个正则表达式 regex101.com 在那里你可以快速测试这个正则表达式
      猜你喜欢
      • 2011-03-06
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      • 2012-05-30
      相关资源
      最近更新 更多