I am working on a password checker and I need some help. If possible I need to make the checker as "realistic" as possible. Meaning it needs to actually register the password and have dialogue. I managed to get some guidelines down: Password needs to be 8-12 Characters, 1 number, 1 special character, and a Capital letter. Im having trouble with storing the password into a database and not allowing two of the same character in consecutive order(Ex. aa)
import java.util.Scanner;
public class passworChk{
public static void main(String[] args) {
// TODO Auto-generated method stub
int min =8;
int max=12;
int digit=0;
int special=0;
int upCount=0;
int loCount=0;
int count=0;
String password;
String decision;
Scanner scan = new Scanner(System.in);
System.out.println("Enter Your Password: ");
password = scan.nextLine();
//Sees if the Password is okay
if(count <= 0){
System.out.println("No password registered. would you like to register a new password? Enter yes or no.");
decision = scan.nextLine();
if(decision.length() == 3){
System.out.println("Enter Your Password: ");
password = scan.nextLine();
count++;
}
else if(decision.length() == 2){
System.out.println("Goodbye");
System.exit(0);
}
}
if(count >= 0){
if(password.length()>=min&&password.length()<=max){
for(int i =0;i<password.length();i++){
char c = password.charAt(i);
//This code goes through the 'password' String and registers it through counts.
if(Character.isUpperCase(c)){
upCount++;
}
if(Character.isLowerCase(c)){
loCount++;
}
if(Character.isDigit(c)){
digit++;
}
if(password.contains("&") || password.contains("!") || password.contains("#") || password.contains("#") || password.contains("$") || password.contains("*") || password.contains("%") || password.contains("?")){
special++;
}
}//If all the counts are in the correct ranges, the password is acceptable.
if(special>=1&&loCount>=1&&upCount>=1&&digit>=1){
System.out.println("Your Password is acceptable.");
}
}
if(password.length()<min){
for(int i =0;i<password.length();i++){
char c = password.charAt(i);
if(Character.isLowerCase(c)){
loCount++;
}
}
if(loCount>0){
System.out.println("Your Password must be at least "+min+" characters.");
System.out.println(" You need at least one upper case chracter,");
System.out.println(" You need at least one digit.");
System.out.println(" You need at least one special chracter.");
}
}
else if(password.length()<min&&upCount>1){
for(int i =0;i<password.length();i++){
char c =password.charAt(i);
if(Character.isLowerCase(c)){
loCount++;
}
if(Character.isUpperCase(c)){
upCount++;
}
}
if(loCount>0&&upCount>0){
System.out.println(" Password must be at least "+min+" chracters:");
System.out.println(" You need at least one digit:");
System.out.println(" You need at least one special chracter:");
}
}
if(password.length()>max||password.length()>=max&&upCount>1&&loCount>1&&digit>1){
System.out.println(" Password is too long. The limit is "+max+" chracters:");
System.out.println(" You need at least one special chracter:");
}
if(password.length()>=min&&password.length()<=max&&loCount>0&&upCount>0&&digit>0&&special==0){
System.out.println(" You need atleast a special chracter");
}
if(password.length()>=min&&password.length()<=max&&loCount>0&&upCount>0&&digit==0&&special==0){
System.out.println(" You need at least one digit:");
System.out.println(" You need at least one special chracter:");
}
}
}
}
In my opinion, instead of having a count of all the special characters, uppercase, and lowercase, you could just have a boolean of each and if at the end all of them are true, you could insert the password into the database. For blocking passwords that have equal characters next to them, you could try something like this within the for loop.
if(i < (password.length() -1) && c == password.charAt( i+1 ) ) {
//throw error message or set boolean of valid to false.
}
This says if i is less than length - 1 (so we can check the next index without array out of bounds exception), then check to see if the next char is equal to the current char.
Next, as some others have said, you should be storing passwords in a database as salted hashes. This is to make sure if your database is compromised, your passwords are hashed.
Related
Password should consist of minimum 8 characters.
Password should consist both numbers and letter.
No special characters are allowed.
The output of this code is always "Invalid Password"
What should be modified to get the correct output?
import java.util.*;
import java.lang.String;
import java.lang.Character;
public class password {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter a Password: ");
String password = input.next();
if (isValid(password)) {
System.out.println("Valid Password");
} else {
System.out.println("Invalid Password");
}
}
public static boolean isValid(String password) {
if (password.length() < 8) {
return false;
} else {
for(int i = 0; i <= password.length() - 1; i++) {
char c = password.charAt(i);
if (!Character.isLetter(c) | !Character.isDigit(c)) {
return false;
}
}
}
return true;
}
}
| is a bitwise or, || is a logical or. You should know the difference.
Work this way though:
if(!Character.isLetter(c) && !Character.isDigit(c))
return false;
=> If the character is not a letter nor a digit return false
You have only one | in your code when doing the OR in your if statement. It should be || . I was stumped on the same thing for an hour yesterday :l
| is a bitwise operator, || is a logical operator. Also, there is a problem with the logic. A Character can't be a Letter and Digit at the same time, so this condition is always true. Try using &&
if(!Character.isLetter(c) && !Character.isDigit(c))
return false;
I feel that I should mention a few mistakes in your approach, as it might help save you time in the future.
If your method isValid, you have a loop which iterates over all the characters in the string. This is the right way to do this, so you clearly know what you need to do to achive the aim.
However, logically, what this method does next is as follows.
Get the first character in the string
Check if the character is a digit or a char
If that character is not a digit or char, return false
Your method will fall over if the first character is not a char, or not a digit. Rationally, you have the right idea, but a letter is not a number, and vise versa.
Suppose the first letter is 'A' - it's not a number, so return false.
If the first character is '1' - it's not a letter, so return false.
As you have seen, changing the operator to && will stop the program failing if you enter only numbers or letters, but will return false if you add any non alphanumeric value.
If you need to enforce at least one digit and at least one number, you have to store the number of digits and chars you have in the string as you iterate over it.
Have two variables, one to store the total number of digits, and one to store the number of chars, and increment them as you step through the string.
If the total number of digits found is greater than zero, and the total number of letters found is greater than zero, your password is valid.
import java.util.*;
import java.lang.String;
import java.lang.Character;
public class password {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter a Password: ");
String password = input.next();
if (isValid(password)) {
System.out.println("Valid Password");
} else {
System.out.println("Invalid Password");
}
}
public static boolean isValid(String password) {
if(password.length()<8) {
return false;
} else {
int dCount = 0;
int cCount = 0;
for (int i=0; i<=password.length()-1; i++) {
char c=password.charAt(i);
if(Character.isLetter(c) {
cCount++;
}
if(Character.isDigit(c)) {
dCount++;
}
}
return dCount > 0 && cCount > 0;
}
}
The prompt is:
Write a Java program to read a string (a password) from the user at the command line and then check that the password conforms to the corporate password policy.
The policy is:
1) the password must be at least 8 characters
2) the password must contain one upper case letter
3) the password must contain one digit.
Use a while loop to step through the string.
Output “Password OK” if the password conforms, otherwise
Output “Password does not conform to the policy.”
I have this down, and it seems to not work still:
String password = "";
boolean hasDigitAndUpper = false;
boolean hasUpper = false;
int i = 0;
System.out.print("Please enter a password: ");
password = scnr.nextLine();
if (Character.isUppercase(password.charAt(i))){
if (Character.isUppercase(password.charAt(i))) {
i++;
hasDigitAndUpper = true;
}
}
while (password.length() < 8 || hasDigitAndUpper != true) {
System.out.println("Password does not conform to policy");
System.out.print("Please enter a password: ");
password = scnr.nextLine();
}
System.out.println("Password OK");
I guess my biggest issue is my boolean which I can't figure out how to fix.
Just some hints:
if (Character.isUppercase(password.charAt(i))){
if (Character.isUppercase(password.charAt(i))) {
i++;
hasDigitAndUpper = true;
}
}
Further down you are using a while-loop. So you have heard of loops before. Hint: you want to for-loop the whole string and check all chars. In my passwords, the uppercase characters usually turn up later behind index 0 or 1.
Then:
while (password.length() < 8 || hasDigitAndUpper != true) {
System.out.println("Password does not conform to policy");
System.out.print("Please enter a password: ");
password = scnr.nextLine();
}
Will not do anything reasonable. You want that loop around the other code. This code just loops and asks the user to enter a new password that has 8 chars - that other boolean hasDigitAndUpper has its old value.
So: you want to write one little method per criteria; and then your code goes:
while (not-all-criteria) {
password = new user input
check password length
check password has upper case
...
Hope that is enough to get you going , and please understand that I am not going to do your homework for you. You are in urgent need to practice those things yourself!
You can use this simple function. This iterates over the password and checks the conditions. If all conditions are satisfied then it returns true, Else false.
public static boolean isValid(String pwd)
{
if (pwd == null || pwd.length() < 8)
{
return false;
}
boolean containUpper = false;
boolean containDigit = false;
int i = 0;
while (i < pwd.length())
{
if (containDigit && containUpper)
{
break;
}
if (Character.isUpperCase(pwd.charAt(i)))
{
containUpper = true;
}
if (Character.isDigit(pwd.charAt(i)))
{
containDigit = true;
}
i++;
}
return containDigit & containUpper;
}
So I'm trying to get this to take user input as a string and check the password to make sure of these two things:
The password is a minimum of 8 characters.
The password only contains letters and numbers.
Now the problem is this:
Checking the password for a minimum of 8 characters works, but checking it to make sure it only contains letters and numbers does not work. It simply terminates without giving a single message if the minimum amount of numbers/letters are entered. However if it sees a character that is not a letter or number, it will print out this:
Please enter a password: ###
Password can only contain letters and numbers.
Password can only contain letters and numbers.
Password can only contain letters and numbers.
Password accepted!
What it should output is this:
Please enter a password: ###
Password can only contain letters and numbers.
or
Please enter a password: test1234
Password accepted!
password.java
package Password;
import java.util.Scanner;
public class Password {
public static void main(String[]args)
{
Scanner input = new Scanner (System.in);
boolean valid = true;
System.out.println("Please enter a password:");
String password = input.nextLine();
int i = 0;
//declares i as the counter varible to control the loop and initializes it to 0
if((password.length( ) < 8 )) //check the passwords length and make sure it's a minimum of 8 characters
{
System.out.println("Password must have at least 8 characters.");
valid = false;
}
//loops the code below it for the length of i until the password length is reached
while(i < password.length())
{
if ((password.charAt(i)>='a' && password.charAt(i)<='z') || (password.charAt(i)>='A' && password.charAt(i)<='Z') ||(password.charAt(i)>='0' && password.charAt(i)<='9'))
//loop through all the characters in the string entered and make sure they only consist of letters and numbers
valid = true;
else
{
System.out.println("Password can only contain letters and numbers.");
valid = false;
}
i++;
//add an iteration to the loop
}
if(!valid == true)
System.out.println("Password accepted!");
}
}
Any help at all with this would be great.
You could simplify the code a bit, first start with valid by checking the password.length(); then test each character in the password (stopping if any are invalid). Then finally check if the password was valid before displaying your accepted message. Like,
Scanner input = new Scanner(System.in);
System.out.println("Please enter a password:");
String password = input.nextLine();
boolean valid = password.length() >= 8;
if (!valid) {
System.out.println("Password must have at least 8 characters.");
} else {
for (char ch : password.toCharArray()) {
if (!Character.isLetter(ch) && !Character.isDigit(ch)) {
System.out.println("Password can only contain letters and numbers.");
valid = false;
break;
}
}
}
if (valid) {
System.out.println("Password accepted!");
}
the main error in this check code is the while loop,when you see a wrong character there is no need to continue the loop,simply you do this kind of checks in that way :
String toCheck; //the string to check some criteria
boolean valid = true; // we assume that nothing wrong happen till now
for(int i=0;i<toCheck.length();i++){ //loop over the characters
if(/*condition of wrong case*/){
valid = false; //mark that something wrong happen
break; //exit the loop no need to continue
}
}
if(valid){
//nothing wrong happen
} else {
//something wrong happen
}
so my online AP Comp Sci teacher isn't responding to me and I'm running into problems with my program. I need to create a random password generator according to user input from this list:
System.out.println("※※※※※※※※※※※※※※※※※※※ | Password Generation Menu | ※※※※※※※※※※※※※※※※※※※");
System.out.println("※|==========================================================================|※");
System.out.println("※| [1] Lowercase Letters |※");
System.out.println("※| [2] Lowercase and Uppercase Letters |※");
System.out.println("※| [3] Lowercase, Uppercase and Numbers |※");
System.out.println("※| [4] Lowercase, Uppercase, Numbers and Symbols |※");
System.out.println("※| [5] Quit |※");
System.out.println("※|==========================================================================|※");
System.out.println("※※※※※※※※※※※※※※※※※※※※※※ | Your selection? | ※※※※※※※※※※※※※※※※※※※※※※※");
So far I'm running into problems
int selection = in.nextInt();
if (selection ==1)
{
System.out.println("How many characters will me used in the password? (1 - 14)");
int chars = in.nextInt();
while ( count <= chars)
{
int password;
password += rand.nextInt((122 - 97) + 1)+ 97;
count++;
}
System.out.println("Password: " + password);
}
else if (selection ==2)
{
System.out.println("How many characters will me used in the password? (1 - 14)");
int chars = in.nextInt();
while ( count <= chars)
{
while( !(randNum>=65 && randNum<=90)&& !(randNum>=97 && randNum<=122))
{
randNum = randNumList.nextInt();
int password;
password += randNum;
}
count++;
}
System.out.println("Password: " + password);
}
else if (selection ==3)
{
System.out.println("How many characters will me used in the password? (1 - 14)");
int chars = in.nextInt();
while ( count <= chars)
{
while( !(randNum>=65 && randNum<=90)&& !(randNum>=97 && randNum<=122)&& !(randNum>=48 && randNum<=57))
{
randNum = randNumList.nextInt();
int password;
password += randNum;
}
count++;
}
System.out.println("Password: " + password);
}
else if (selection ==4)
{
System.out.println("How many characters will me used in the password? (1 - 14)");
int chars = in.nextInt();
while ( count <= chars)
{
int password;
password += rand.nextInt((126 - 35) + 1)+ 35;
count++;
}
System.out.println("Password: " + password);
}
else if (selection ==5)
{}
else
{
System.out.println(" ERROR: " + selection + " is not on the menu ");
}
}
Its saying the variable password cannot be found, is this because of the loop? I'm utterly stumped and frustrated as I'm falling behind on my work
(This is my first time asking on this site sorry if its formatted weird)
There are few problems.
Scope
One is the notion of scope. Each variable has a scope, which defines when the variable can be accessed and how long it stores data.
Each of your options, 1-4, is creating one password with a different method, and each of those methods uses a loop to add characters to a password. So, each method should have a variable to store the password while characters are added. In general, the structure could be something like this:
if (selection == 1) {
System.out.println("How many characters?");
int chars = in.nextInt();
StringBuilder password = new StringBuilder(chars);
for (int count = 0; count < chars; ++count) {
password.append((char) ('A' + rand.nextInt(26)));
}
System.out.println("Your password is: " + password);
} else if (selection == 2) {
...
The key to notice here is that we defined a variable, password, outside of the loop that adds characters. This means that the value of password will be maintained across each iteration of the loop.
Once the enclosing block (if (selection == 1) { ...) is exited, however, the variable password doesn't exist anymore, and its content is no longer accessible. That means that you can declare another variable named password inside the block that handles the next option, that is completely unrelated to the password in the first block. It doesn't even have to be the same type.
That's how scope works: a variable defined in a scope is visible to any scopes nested within, but when the scope is exited, the variable no longer exists.
Data types
I am assuming that you are trying to generate passwords with letters, numbers, and symbols—a sequence of characters. There are a few different ways to represent text in Java, but I demonstrated above the most convenient option for this problem, a StringBuilder. You will notice that I use a cast, (char), when I append() each character. That's because the result of adding integers is an integer. StringBuilder has many append() methods that take different data types. If you append a char, that character is appended. But if you append an int, a series of characters representing that numeric value in decimal is appended. By casting to a char, we pick the right version of append().
Factoring
You repeat a lot of code. A better structure would avoid that, by "hoisting" common code out of sub-blocks.
int selection = in.nextInt();
System.out.println("How long?");
int chars = in.nextInt();
StringBuilder password = new StringBuilder(chars);
for (int count = 0; count < chars; ++count) {
if (selection == 1) {
password.append((char) ('A' + rand.nextInt(26));
} else if (selection == 2) {
...
}
}
System.out.println("Your password is: " + password);
This saves you from repeating the prompts, input and output processing, declaration and initialization of the password variable, etc. It makes your code shorter, and if you find a bug, you are more likely to fix it in one place, rather than in every supported option.
As learn more, you'll find better ways to handle the different options, by factoring the character generation into another object, which you choose once, before entering the loop. That way you don't have to constantly re-evaluate which option was selected.
I have the majority of my program finished, but now that I have most of the code it is tough to find the errors. I have multiple errors at the moment, but the main error I really need help with is that my program will loop the same guess over & over if it is correct. It is in an infinite loop, & I cannot find where it is. This has also brought to my attention that my program will go into negative guesses as it is supposed to end when it gets to 0. Some other errors that would be nice to get help with is 1) it shows a correct guess as an incorrect guess 2) it can only replace one letter in the secret word if there are multiple it will give me an error & end the program. & 3) if I enter 9 to quit, it does not quit.
Thanks in advance for any help. I can add code if needed ( I am only posting the main body ATM.)
public static final int DICTIONARY = 15000;
public static final int GUESSES = 8;
public static final int SECRETLENGTH = 20;
public static void main(String[] args) {
int usedSize = 0, randomWord, guesses = GUESSES;
String word, secretWord, guess, incorrectGuess, correctWord, playAgain;
char letter;
try
{
// Set up connection to the input file
Scanner hangmanDictionary = new Scanner(new FileReader("dictionary.txt"));
String [] dictionary = new String [DICTIONARY];
while (usedSize < DICTIONARY && hangmanDictionary.hasNextLine()) {
dictionary[usedSize] = hangmanDictionary.nextLine();
usedSize++;
}
kbd.nextLine();
clearScreen();
randomWord = pickRandom(DICTIONARY);
word = dictionary[randomWord];
secretWord = secret(word);
//comment out when done testing
System.out.println(word);
System.out.println("Here is the word to guess: " + secretWord);
System.out.println("Enter a letter to guess, or 9 to quit.");
guess = kbd.next();
do {
while (!guess.equals("9") || !(guess.equals(word) && guesses > 0)) {
letter = guess.charAt(0);
incorrectGuess = "";
incorrectGuess += letter;
if (word.indexOf(letter) < 0) {
guesses--;
System.out.println("Incorrect guesses: " + incorrectGuess);
System.out.println("Number of guesses left: " + guesses);
System.out.println("Enter a letter to guess, or 9 to quit.");
guess = kbd.next();
}
else {
//FINSH THIS
correctWord = correctWord(guess, word, secretWord, letter);
System.out.println(correctWord);
System.out.println("Incorrect guesses: " + incorrectGuess);
System.out.println("Number of guesses left: " + guesses);
System.out.println("Enter a letter to guess, or 9 to quit.");
guesses--;
}
}
if (guess.equals("9")) {
System.out.println("Thanks for playing!");
System.exit(0);
}
if (guess.equals(word)) {
System.out.println("You won!");
}
if (guesses == 0) {
System.out.println("You are out of guesses.");
}
System.out.println("Play again? Y/N");
playAgain = kbd.nextLine().toUpperCase();
} while (playAgain.equals("Y"));
}
catch (FileNotFoundException e) {
System.out.println("There was an error opening one of the files.");
}
}
Here's my guess:
Did you forget to put guess = kbd.next(); if the user guessed a correct character?
The inner while loop is your main problem, i.e. think about what happens when you enter a valid letter (guess), in that case the first condition of the while loop OR condition is TRUE (assuming you don't have a 9 in your secret word), so the while loop is entered without entering the second part of the OR condition. After that you enter the else part of the IF statement (since it's a valid guess) but in the else part you're not asking for the next guess, so it returns to the start of the while loop with the same guess and hence infinite loop.
Similarly, if you enter 9 to exit !guess.equals("9") evaluates to FALSE, so the second part of the OR condition is entered, in the second part
!(guess.equals(word) && guesses > 0) evaluates to TRUE (unless the secret word contains a 9) so you enter the WHILE loop which is invalid. etc ...
Try to write small parts of the code using known parameters and then bring it all together, that way it'll be easier to construct and follow the logic.