Reputation: 65
I am trying to create a program that will take input from user as a password and compare to see if the password meets the requirements. If it doesn't meet requirements, re-prompt user for password again until it meets the requirements. Here is what I have and I don't understand why it doesn't work...
import javax.swing.*;
public class Password {
public static void main(String[] args) {
//
String pInput = "";
do {
pInput = JOptionPane.showInputDialog(null, "Please enter your password.\n"
+ "Your password must have 6-10 characters\n"
+ "Your password must contain at least one letter and one digit");
}
while (authenticate(pInput) == false);
JOptionPane.showMessageDialog(null, "Your password was successfully entered.");
}
private static boolean authenticate(String password)
{
// The password should be at least six characters long.
// The password should contain at least one letter.
// The password should have at least one digit.
if ((password.length() > 6) &&
(password.length() < 10) &&
(password.matches("[a-z]")) &&
(password.matches("[0-9]")))
return true;
else
return false;
}
}
Upvotes: 2
Views: 4445
Reputation: 154
I think problem is in function's if block, use following code
if ((password.length() >= 6) &&
(password.length() <= 10) &&
(password.matches(".*[a-z]+.*")) &&
(password.matches(".*[0-9]+.*")))
return true;
Upvotes: 0
Reputation: 201447
If I understand your question, I would rename your authenticate()
method (it's really validate()
),
// validate that a password adheres to the "rules".
private static boolean validate(String password) {
// Check for null, then a length less then 6 (and I really don't like the length()
// > 10 check, that's a BAD requirement).
if (password == null || password.length() < 6 || password.length() > 10) {
return false;
}
boolean containsChar = false;
boolean containsDigit = false;
for (char c : password.toCharArray()) {
if (Character.isLetter(c)) {
containsChar = true;
} else if (Character.isDigit(c)) {
containsDigit = true;
}
if (containsChar && containsDigit) {
return true;
}
}
return false;
}
Personally, I would prefer to avoid a regex because they are often confusing. If it's a requirement, then the one added as a comment to the question by @MadProgrammer might be used,
private static final Pattern pattern = Pattern
.compile("^(?=.*\\d)(?=.*[a-zA-Z]).{6,10}$"); // <-- note "\\d"
private static boolean validate(String password) {
return pattern.matcher(password).matches();
}
Upvotes: 3
Reputation: 53535
Change the regex in the authentication method:
private static boolean authenticate(String password)
{
// The password should be at least six characters long.
// The password should contain at least one letter.
// The password should have at least one digit.
if ((password.length() >= 6) &&
(password.length() <= 10) &&
(password.matches("^(?:.*[a-z].*)(?:.*[0-9].*)$")))
return true;
else
return false;
}
Using non-capturing lookahead patterns will enable the validation you want. The original version did not work because it was trying to match the password to: "[a-z]" and "[0-9]" simultaneously - a condition that will always return false!
Upvotes: 1
Reputation: 33
you should change :
password.length() >6 into password.length() >= 6
password.length() <10 into password.length() <=10
because you want at least six characters long. and most ten characters long.
password.matches("[a-z]") into password.matches(".[a-z]+.") because .matches("[a-z]") is used for check a character not for string
this one is edited version
private static boolean authenticate(String password)
{
// The password should be at least six characters long.
// The password should contain at least one letter.
// The password should have at least one digit.
if ((password.length() >= 6) &&
(password.length() <= 10)&&
(password.matches(".*[a-z]+.*")) &&
(password.matches(".*[0-9]+.*")) )
return true;
else
return false;
}
}
Upvotes: 2
Reputation: 3778
You need to change:
password.length() > 6
into: password.length() >= 6
password.length() < 10
into: password.length() <= 10
(password.matches("[a-z]")) && (password.matches("[0-9]"))
into: password.matches(".*[a-z]+.*") && password.matches(".*[0-9]+.*")
The first two are because you want the 6-10 range to be inclusive (so it sounds from your requirements).
The third change is because you need the regular pattern to match the entire password, not just a single character.
Upvotes: 0