I have an assignment that requires me to create a password checking program.
The password must be at least 8 characters, contain both capital and lower case letters, a digit and a special character.
I believe I am close to solving this problem but my skills are still developing and I've hit a wall.
package project1;
/**
*
* #author danechristian
*/
import java.util.*;
public class Project1
{
static Scanner console = new Scanner(System.in);
static final String SPECIAL_CHARACTERS = "!,#,$,%,^,&,*,|";
static String password;
public static void main(String[] args)
{
System.out.println("Create a password: ");
password = console.next();
if (validPassword(password))
{
System.out.println("Password Saved");
}
else
{
System.out.println("Invalid Passowrd. Password "
+ "must contain atleast 1 capital letter"
+ "1 lower case letter, 1 digit, 1"
+ "special character (!#$%^&*|) and "
+ "be atleast 8 characters long");
}
}
public static boolean validPassword(String password)
{
boolean upCase = false;
boolean loCase = false;
boolean isDigit = false;
boolean spChar = false;
if (password.length() >= 8)
{
for (int i = 0; i < password.length() - 1; i++)
{
if (Character.isUpperCase(password.charAt(i)))
{
upCase = true;
}
if (Character.isLowerCase(password.charAt(i)))
{
loCase = true;
}
if (Character.isDigit(password.charAt(i)))
{
isDigit = true;
}
if (SPECIAL_CHARACTERS.contains(password))
{
spChar = true;
}
}
}
return (upCase && loCase && isDigit && spChar);
}
}
In order to check have something like this:
public static boolean validPassword(String password){
boolean upCase = false;
boolean loCase = false;
boolean isDigit = false;
boolean spChar = false;
if (password.length()>7){
if (password.matches(".+[A-Z].+")){
upCase = true;
}
if (password.matches(".+[a-z].+")){
loCase = true;
}
if (password.matches(".+[1-9].+")){
isDigit = true;
}
if (SPECIAL_CHARACTERS.contains(password)){
spChar = true;
}
}
return (upCase && loCase && isDigit && spChar);
}
solved by changing
if (SPECIAL_CHARACTERS.contains(password)){
spChar = true;
to
if (SPECIAL_CHARACTERS.contains(password.substring(i,i+1))){
spChar = true;
this checks for the string within the string.
also, I removed the "- 1" from my for statement so that the bounds were corrects. also removed the commas from the SPECIAL_CHARACTERS constant.
the program now runs without issue, thanks for the advice everyone.
Related
I need to have following password validations :
At least Min Characters 8 and Maximum Characters 15
At least One Number and 1 special characters from (! ##$%^&*-=+?.);
At least One lower case letter
Password shouldn't be sub strings of username and email (min length 3 and max length 15).
Password should be case sensitive.
I have also looked these answers but I am confuse , should I use Input filters to achieve this or Regex?
Any help will be appreciable. It will be great if you guyz provide a working solution.
public class Validation {
public static void main(String[] args) {
String pass = "1AB%CDef555";
String username = "manna";
String email = "mannx#rtt.com";
System.out.println(validiate2(pass, username,email));
}
// if you don't care why it fails and only want to know if valid or not
public static boolean validiate (String pass, String username, String email){
String pattern = "^(?=.*[0-9])(?=.*[a-z])(?=.*[!##$%^&*+=?-]).{8,15}$";
if(pass.matches(pattern)){
for(int i=0;(i+3)<username.length();i++){
if(pass.contains(username.substring(i,i+3)) || username.length()<3 || username.length()>15){
return false;
}
}
for(int i=0;(i+3)<email.length();i++){
if(pass.contains(email.substring(i,i+3)) || email.length()<3 || email.length()>15){
return false;
}
}
return true;
}
return false;
}
// if you want to know which requirement was not met
public static boolean validiate2 (String pass, String username, String email){
if (pass.length() < 8 || pass.length() >15 ){
System.out.println("pass too short or too long");
return false;
}
if (username.length() < 3 || username.length() >15 ){
System.out.println("username too short or too long");
return false;
}
if (!pass.matches(".*\\d.*")){
System.out.println("no digits found");
return false;
}
if (!pass.matches(".*[a-z].*")) {
System.out.println("no lowercase letters found");
return false;
}
if (!pass.matches(".*[!##$%^&*+=?-].*")) {
System.out.println("no special chars found");
return false;
}
if (containsPartOf(pass,username)) {
System.out.println("pass contains substring of username");
return false;
}
if (containsPartOf(pass,email)) {
System.out.println("pass contains substring of email");
return false;
}
return true;
}
private static boolean containsPartOf(String pass, String username) {
int requiredMin = 3
for(int i=0;(i+requiredMin)<username.length();i++){
if(pass.contains(username.substring(i,i+requiredMin))){
return true;
}
}
return false;
}
}
There is great library for that.
It's uses anotations for field and has rich customatization.
I think that #4 still needs to be done by hand but you should definitly check out the library.
Here's the example from github:
#Password(min = 6, scheme = Password.Scheme.ALPHA_NUMERIC_MIXED_CASE_SYMBOLS)
private EditText passwordEditText;
Cheers.
You can try this one:
^(?!.*(user|emailaddress))(?=.*\d)(?=.*[! ##$%^&*=+?.-])(?=.*[a-z]).{8,15}$
Make sure you replace the user and emailaddress by your variable
Explanation
This code works fine for me:
public class NewClass1 {
public static void main(String[] args) {
NewClass1 nc = new NewClass1();
nc.check("abcd123-", "userName", "abc#yahoo.com");
nc.check("userName1-", "userName", "abc#y.c");
nc.check("abc#y.c1b", "userName", "abc#y.c");
nc.check("abcy.c1b", "userName", "abc#y.c");
nc.check("abcd123-", "userName", "abc#yahoo.com");
}
public void check(String string, String userName, String email) {
final String regex = "^(?!.*(" + userName + "|" + email + "))(?=.*\\d)(?=.*[! ##$%^&*=+?.-])(?=.*[a-z]).{8,15}$";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
System.out.println(string + "Full match: " + matcher.group(0));
} else {
System.out.println("no match");
}
}
}
Hey guys i have this code I am working on for a class and I can't figure out what I've screwed up. I'm sure its something simple, so if you could look at it I and help me with my mistake.
Background: This is supposed to check a word to make sure it contains a punctuation char, an Uppercase letter and a lowercase letter, and a number with in the first 8 digits.
When I step through it in netbeans the for loop will only go to the second if statement before returning to the top and iterating again. it won't enter the if statement concerning the numFlag or the upperFlag and lowerFlag
I have those if statements checking to see if the flags are true or not so that if I have already detected the corresponding char type it wont enter and continue on.
It does compile, and runs i have included the main method I'm using to test as well for convenience if you want to compile and test it
Any other suggestions are welcome as well. If I haven't provided enough info please let me know what you need.
Problematic Code:
public final class Checker {
private Checker() {}
public static boolean checkLegality(String _pass) {
boolean puncFlag = false;
boolean numFlag = false;
boolean upperFlag = false;
boolean lowerFlag = false;
char[] pass = _pass.toCharArray();
if (pass.length < 8) {
return false;
}
for (int i = 0; i < 9; i++) {
if (!puncFlag) {//enters check for puncuation only if it hasint detected any yet
int ascii = (int) pass[i];//converts to ascii
if (32 < ascii && ascii < 47) {
puncFlag = true;
}
} else if (!numFlag) {//enters check for numbers only if it hasint detected any yet
if (Character.isDigit(pass[i])) {
numFlag = true;
}
} else if (!upperFlag || !lowerFlag) {//enters check for letters only if it hasint detected both upper and lower yet
if (Character.isLetter(pass[i])) {
if (Character.isUpperCase(pass[i])) {//checks if upper case
upperFlag = true;
} else if (Character.isLowerCase(pass[i])) {
lowerFlag = true;
}
}
}
}
if (puncFlag
&& numFlag
&& upperFlag) {
return true;
} else {
return false;
}
}
}
Main Method I use to test
public class PasswordCheckermMain {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//TO DO CODE HERE
Scanner in = new Scanner(System.in);
String pass;
boolean flag = false;
while (flag == false) {
System.out.println("Enter password: ");
pass = in.next();
if(Checker.checkLegality(pass)){
flag = true;
}
System.out.println("The password meets criteria: " + flag);
}
}
}
You shouldn't do the tests in the else-if because then all the checks won't be done unless the previous was done.
E.g.
if (!puncFlag) {//enters check for puncuation only if it hasint detected any yet
...
}
if (!numFlag) {//enters check for numbers only if it hasint detected any yet
...
}
if (...)
Sidenote, you don't have to do
if (32 < ascii && ascii < 47) {
This will work
if (' ' < pass[i] && pass[i] < '/') {
numFlag only gets true when you see a digit, otherwise it stays false. When it's false, you get inside the if statement and do nothing else. So if you pass a password with only letters, you will never set numFlag to true, and never check for letters.
I think you shouldn't read the flags at all. You should read each character and check if it's a punctuation sign (set the flag) a number(set the flag) or letters (set appropriate flags).
Why do you even check if a flag is already set? Just "or together" the results. Also, if you shorten the String with substring, you can use a "foreach" loop. And you don't have to cast a char in order to compare its value with an int:
public static boolean checkLegality(String _pass) {
boolean puncFlag = false;
boolean numFlag = false;
boolean upperFlag = false;
boolean lowerFlag = false;
if (_pass.length() < 8) {
return false;
}
char[] pass = _pass.substring(0,8).toCharArray();
for(char c : pass) {
puncFlag = puncFlag || (32 < c && c < 47);
upperFlag = upperFlag || (Character.isLetter(c) && Character.isUpperCase(c));
lowerFlag = lowerFlag || (Character.isLetter(c) && Character.isLowerCase(c));
numFlag = numFlag || Character.isDigit(c);
}
return puncFlag && upperFlag && lowerFlag && numFlag;
}
From what I see, if your password is 8 characters long, it will crash because you check the first 9 characters.
Your loop should be :
for (int i = 0; i < 8; i++) {
...
because the last index of a 8 elements array is 7 (since the first index is 0).
UPDATE
As mentioned in other answers, you shouldn't use else if but separate if statements if you want to allow to have letters before punctuation or numbers and so on...
May I also suggest you to check this by using a regular expression, which should do the same job in fewer lines.
Basically i done is to change else if(if (!numFlag) for just if, add the try{ }catch(excepction e){ } for any unlike output. Also in the main class, i change the Scanner in for inn and close inn properly.
PasswordCheckermMain class
import java.util.Scanner;
public class PasswordCheckermMain {
public static void main(String[] args) {
//TO DO CODE HERE
Scanner inn = new Scanner(System.in);
String pass;
boolean flag = false;
while (flag == false) {
System.out.println("Enter password: ");
pass = inn.next();
if(Checker.checkLegality(pass)){
flag = true;
}
System.out.println("The password meets criteria: " + flag);
}
inn.close();
}
}
Checker class
public class Checker {
private Checker() {}
public static boolean checkLegality(String _pass) {
boolean puncFlag = false;
boolean numFlag = false;
boolean upperFlag = false;
boolean lowerFlag = false;
int ascii =0;
char[] pass = _pass.toCharArray();
//adding try{ }catch{} for better programing
try{
if (pass.length < 8) {
return false;
}
for (int i = 0; i < 8; i++) {
if (!puncFlag) {
//if 1 enters check for puncuation only if it hasint detected any yet
ascii = (int) pass[i];//converts to ascii
if (32 < ascii && ascii < 47) {//if2
puncFlag = true;
}//end if2
}//end if 1
//Note change else if for if
if (!numFlag) {
//enters check for numbers only if it hasint detected any yet
if (Character.isDigit(pass[i])) {
numFlag = true;
}
} else if (!upperFlag || !lowerFlag) {//enters check for letters only if it hasint detected both upper and lower yet
if (Character.isLetter(pass[i])) {
if (Character.isUpperCase(pass[i])) {//checks if upper case
upperFlag = true;
} else if (Character.isLowerCase(pass[i])) {
lowerFlag = true;
}
}
}
}//end for
if (puncFlag && numFlag && upperFlag && lowerFlag ) {
return true;
} else {
return false;
}
}catch(Exception e){ return false; }
}//end checklega
OUTPUT :
Enter password:
12#Abxyz
The password meets criteria: false
Enter password:
12.Abxyz
The password meets criteria: true
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
So this program is supposed to be a game where a user enters a phrase and another user tries to guess the phrase. I'm having a problem with buying a vowel, however. No matter what I enter at line 41 (, it just goes past the loop. I made the validAnswer(String answer) method in the hopes that it would be useful in the loop but it doesn't look to be much help. I know there is a small thing I'm missing but I'm too new to Java to recognize it yet. What am I doing wrong?
I apologize for the long amount of code.
import java.util.Scanner;
public class PhraseGame {
public static void main(String[] args) {
// Initialize scanner
Scanner stdIn = new Scanner(System.in);
// Initialize variables
String sPhrase;
String answer = "f";
char cGuess = 0;
char vGuess = 0;
int count = 0;
int vowels = 0;
int consonants = 0;
int spaces = 0;
boolean gameOver = false;
boolean correct = true;
// Start the "fun" game
System.out.print("Please enter the phrase to guess at: ");
sPhrase = stdIn.nextLine();
// Create the temporary Array
char [] tmpArr = new char[sPhrase.length()];
for (int i = 0; i < sPhrase.length(); i++) {
tmpArr[i] = sPhrase.charAt(i);
}
// Gets the number of spaces
spaces = initTemplateArray(sPhrase, tmpArr, spaces);
printTemplateArray(tmpArr);
while (!(endGame(gameOver, spaces, consonants, vowels, sPhrase))) {
cGuess = getConsonant(stdIn, cGuess);
do {
System.out.print("\nWould you like to buy a vowel?: ");
answer = stdIn.next();
if (answer == "y") {
getVowel(stdIn, vGuess); }
else if (answer == "n"){
break;
}
} while (!validAnswer(answer));
// Updates the array and prints it
updateTemplateArray(tmpArr, sPhrase, cGuess, vGuess, count, vowels, consonants);
printTemplateArray(tmpArr);
// Checks if the game is over
endGame(gameOver, spaces, consonants, vowels, sPhrase);
}
}
// returns the number of space characters used in the common phrase
public static int initTemplateArray(String sPhrase, char [] tmpArr, int spaces) {
for (int i = 0; i < sPhrase.length(); i++) {
if (tmpArr[i] != ' ') {
tmpArr[i] = '?';
} else {
tmpArr[i] = ' ';
spaces++;
}
}
return spaces;
}
public static void printTemplateArray(char [] tmpArr) {
System.out.println("\nCommon Phrase");
System.out.println("-------------");
for (int i = 0; i < tmpArr.length; i++) {
System.out.print(tmpArr[i]);
}
}
public static boolean isVowel(char c) {
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}
public static char getConsonant(Scanner stdIn, char cGuess) {
do {
System.out.println("\nEnter a lowercase consonant guess: ");
cGuess = stdIn.next().charAt(0);
} while (isVowel(cGuess));
return cGuess;
}
public static char getVowel(Scanner stdIn, char vGuess) {
do {
System.out.println("\nEnter a lowercase vowel guess: ");
vGuess = stdIn.next().charAt(0);
} while (!(isVowel(vGuess)));
return vGuess;
}
public static int updateTemplateArray(char [] tmpArr, String sPhrase, char cGuess, char vGuess, int count, int vowels, int consonants) {
for (int i = 0; i < sPhrase.length(); i++) {
if (cGuess == sPhrase.charAt(i)) {
tmpArr[i] = sPhrase.charAt(i);
count++;
consonants++;
}
if (vGuess == sPhrase.charAt(i)) {
tmpArr[i] = sPhrase.charAt(i);
count++;
vowels++;
}
}
return count & vowels & consonants;
}
public static boolean endGame(boolean gameOver, int spaces, int consonants, int vowels, String sPhrase) {
int total = spaces + consonants + vowels;
if (total == sPhrase.length()) {
return true;
}
else {
return false;
}
}
public static boolean validAnswer(String answer) {
if (answer.equalsIgnoreCase("y")) {
return true;
}
else if (answer.equalsIgnoreCase("n")) {
return true;
}
else {
return false;
}
}
}
You need to check for null.
public static boolean validAnswer(String answer) {
if (answer!=null && (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("n"))) {
return true;
}
return false;
}
or an other unconventional way.
public static boolean validAnswer(String answer) {
if ("y".equalsIgnoreCase(answer) || "n".equalsIgnoreCase(answer))) {
return true;
}
return false;
}
You need to fix
do {
System.out.print("\nWould you like to buy a vowel?: ");
answer = stdIn.nextLine();
if ("y".equalsIgnoreCase(answer)) {
getVowel(stdIn, vGuess);
} else if ("n".equalsIgnoreCase(answer)){
break;
}
} while (!validAnswer(answer));
I have a Java Assignment where I have to prompt for a line input, check if its a palindrome and then say if the palindrome is made of all text, all numbers, or mixed. I haven't added the part where I check what kind of palindrome it is yet, but I need help with the code to check if it's a palindrome. The code I posted below recognizes everything as a palindrome even if it isn't. This is basic Java so I'm limited to what I used below.
import java.util.Scanner;
public class Project4{
public static void main (String [] args)
{
String line = getInputLine();
while (!isEmptyLine (line))
{
if (isPalindrome (line))
System.out.println ("\"" + line + "\" is a palindrome.");
else
System.out.println ("\"" + line + "\" is not a palindrome");
line = getInputLine();
}
System.out.println ("End of program");
}
public static String getInputLine ( )
{
Scanner in = new Scanner(System.in);
System.out.print("Enter a line of input: ");
String inputline = in.nextLine();
return inputline;
}
public static boolean isEmptyLine(String str)
{
boolean truefalse;
if(str.length()==0)
truefalse = true;
else
truefalse = false;
return truefalse;
}
public static boolean isPalindrome(String str)
{
int left = 0;
int right = str.length();
boolean okay = true;
char ch1; char ch2;
while(okay && left<right)
{
ch1 = str.charAt(left);
if(!Character.isDigit(ch1)||!Character.isLetter(ch1))
left++;
else
{
ch2 = str.charAt(right);
if(!Character.isDigit(ch2)||!Character.isLetter(ch2))
right--;
else
{
ch1 = Character.toUpperCase(ch1);
ch2 = Character.toUpperCase(ch2);
if(ch1==ch2)
{
left++;
right--;
}
else
okay = false;
}
}
}
return okay;
}
}
You need to do logical AND of the 2 checks instead of OR -
if(!Character.isDigit(ch1) && !Character.isLetter(ch1))
Use a method like the following:
boolean isPalindrome (String input) {
int strLength = input.length;
for (int i=0; i < input.length/2; ++i) {
if (input.charAt(i) != input.charAt(strLength-i)) {
return false;
}
}
return true;
}
A late answer although it might help some in the future. The method posted below doesn't use any of StringBuilder functions.
public boolean isPalindrome(String value) {
boolean isPalindrome = true;
for (int i = 0 , j = value.length() - 1 ; i < j ; i ++ , j --) {
if (value.charAt(i) != value.charAt(j)) {
isPalindrome = false;
}
}
return isPalindrome;
}
Hey all I am working on a program in Java that checks a password for a few things such as is it 8 characters, is one character Uppercase, is one lowercase, and is there a number in the password. So far I have wrote the methods for checking length, upper and lower case, with no problems. I cannot for the life of my understand why it isn't working with the isDigit().
No matter what input I throw in the method, it always returns true. Anyone see my error?
Thanks in advance!
public void setOneDigit(){
int i;
char ch;
boolean hasNumber = false;
for ( i = 0; i < password.length(); i++ ) {
ch = password.charAt(i);
if (Character.isDigit(ch));
{
hasNumber = true;
}
}
if(hasNumber == true)
{
hasOneDigit = true;
}
else
{
hasOneDigit = false;
}
}
Classic mistake:
if (Character.isDigit(ch));
{
hasNumber = true;
}
has to be
if (Character.isDigit(ch))
{
hasNumber = true;
}