Password verification not working with a particular sequence - java

i have written this method
public boolean passwordCheck(String password)
{
boolean isValid = false;
int numCount = 0;
if(password.length() < 8){
return false;
}
for(int i = 0; i < password.length(); i++){
if(!Character.isLetterOrDigit(password.charAt(i)))
{
return false;
}
else{
return true;
}
}
return isValid;
}
and when I do passwordCheck("a * b * e * d * c") (imagine no spaces in between the asterisks) it should return false because i have the
if(!Character.isLetterOrDigit(password.charAt(i)))
so since there are things in the password that are not valid characters i would expect it would return false but that is not the case.

You return true after your first character is a letter or digit.

If you use "return" when a character is "unacceptable" (return false) This is OK - because "one bad apple will spoil the bunch".
And also: "One invalid character means the whole password is invalid..." But if you return true just because one character is valid / true. That is the mistake in your method. –
public boolean passwordCheck(String password)
{
if(password.length() < 8) return false;
for(int i=0; i < password.length(); i++)
if(!Character.isLetterOrDigit(password.charAt(i)))
return false;
return true;
}

You don't want to return true until after you've checked every character. But currently, you're returning true as soon as you've checked the first one.
One possible solution is to get rid of the else clause, and move the return true; down outside the loop, like this.
for(int i = 0; i < password.length(); i++){
if(!Character.isLetterOrDigit(password.charAt(i)))
{
return false;
}
}
return true;

Related

The java method Character.isDigit(char) returns true with an input of 'O'

I made a for loop to iterate through a given string and used the Character.isDigit(char) to return true ONlY if all of the letters in the string were digits. For example isInteger("412") returns true. BUT, with an input of the string "1O1" it returns true, which should be false since O is a letter.
public boolean isInteger(String str)
{
for(int i = 0; i < str.length(); i++){
if(Character.isDigit(str.charAt(i))){
return true;
}
}
return false;
}
I also tried making a condition putting:
if(str.charAt(i) != 'O' && Character.isDigit(str.charAt(i))){
return true;
}
But that did not work.
Your method is returning true if ANY of the characters in the string are digits. Two of the characters in 1O1 are digits, so the method will return true.
You need to check if any of the characters is not a digit:
for(int i = 0; i < str.length(); i++){
if(!Character.isDigit(str.charAt(i))){
return false;
}
}
return true;
All of the characters have to be numbers for the condition to be true. If any character is not a number, the condition is false.
public boolean isInteger(String str)
{
if (str == null || str.length() == 0) return false;
for (int i = 0; i < str.length(); i++) {
if(!Character.isDigit(str.charAt(i))) { // not condition
return false;
}
}
return true;
}

Method to Check Password in Java Not Working

I'm trying to write a method that returns if the string is or isn't a valid password in CodeHS.
It needs to be at least eight characters long and can only have letters and digits.
In the grader, it passes every test except for passwordCheck("codingisawesome") and passwordCheck("QWERTYUIOP").
Here's what I have so far:
public boolean passwordCheck(String password)
{
if (password.length() < 8)
{
return false;
}
else
{
char c;
int count = 0;
for (int i = 0; i < password.length(); i++)
{
c = password.charAt(i);
if (!Character.isLetterOrDigit(c))
{
return false;
} else if (Character.isDigit(c))
{
count++;
}
}
if (count < 2)
{
return false;
}
}
return true;
}
If anyone can help, I'd appreciate it. Thanks.
Try an approach using patterns (this is simpler than looping):
public boolean passwordCheck(String password)
{
return password!=null && password.length()>=8 && password.matches("[A-Za-z0-9]*");
}
Decent tutorial on regular expressions (that's where the A-Z magic comes from): http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
Assuming your requirement is as stated
It needs to be at least eight characters long and can only have letters and digits
Then there is no need to count digits. Simply check that the password is the minimum length, then loop over every character returning false if any are not a letter or digit. Like,
public boolean passwordCheck(String password) {
if (password != null && password.length() >= 8) {
for (char ch : password.toCharArray()) {
if (!Character.isLetterOrDigit(ch)) {
return false;
}
}
return true;
}
return false;
}
It's failing those tests because your code checks that the password must have at least 2 digits:-
if (count < 2)
{
return false;
}
And your test strings don't have any. Remove this piece of code and it should work. For a better way of doing it, see other answers.

Trying to return true if all the letters in a string are the same

What I have so far:
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length(); i++)
{
int charb4 = i--;
if ( str.charAt(i) != str.charAt(charb4))
{
return false;
}
if ( i == str.length())
{
return true;
}
}
}
Please excuse any inefficiencies if any; still relatively new to coding in general. Am I lacking some knowledge in terms of using operators and .charAt() together? Is it illogical? Or is my error elsewhere?
Using regex:
return str.matches("^(.)\\1*$");
Using streams:
str.chars().allMatch(c -> c == str.charAt(0));
Other:
return str.replace(String.valueOf(str.charAt(0), "").length() == 0;
You can follow the below steps:
(1) Get the first character (i.e., 0th index)
(2) Check the first character is the same with subsequent characters, if not return false (and comes out from method)
(3) If all chars match i.e., processing goes till the end of the method and returns true
public boolean allSameLetter(String str) {
char c1 = str.charAt(0);
for(int i=1;i<str.length;i++) {
char temp = str.charAt(i);
if(c1 != temp) {
//if chars does NOT match,
//just return false from here itself,
//there is no need to verify other chars
return false;
}
}
//As it did NOT return from above if (inside for)
//it means, all chars matched, so return true
return true;
}
As Andrew said, you are decreasing i within your for loop. You can fix this by changing it to int charb4 = i - 1;. As for making your code more efficient you could condense it down to this.
public boolean allSameLetter(String str) {
for(char c : str.toCharArray())
if(c != str.charAt(0)) return false;
return true;
}
Comment if you don't understand a part of it :)
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length() -1; i++)
{
if ( str.charAt(i) != str.charAt(i+1))
{
return false;
}
}
return true
}
-1 is there since I am checking the current value in the array, then the next value in the array, thus I need to stop a place earlier.
If the loop if statement is never entered, it will make it far enough into the code to return true
You have to create a for loop that searches through the length of the String - 1. this way the program will not crash because of a 3 letter word with the program trying to get the 4th letter. This is what works for me:
public boolean allSameLetter(String str)
{
for(int i = 0; i< str.length()-1; i++){
if (str.charAt(i) != str.charAt(i+1)){
return false;
}
}
return true;
}
if((new HashSet<Character>(Arrays.asList(s.toCharArray()))).size()==1)
return true;
return false;
This should be enough
The bug is caused by
int charb4 = i--;
this line is equal to
int charb4 = i-1;
i=i-1;
Because of this, your loop will never stop.
The easiest way to fix this
public boolean allSameLetter(String str)
{
for (int i = 1; i < str.length(); i++)
{
if ( str.charAt(i) != str.charAt(i-1))
{
return false;
}
}
}

My code won't return anything! output is simply blank

I'm writing this code in java to scan numerical or alphabetical strings to see if they are consecutive. Everything seems to be working fine until I try to place a boolean in there to return true or false but nothing is happening! What am I missing? THanks! :)
Here it is:
public class Question1 {
public static void main(String[]args){
String s = "gFeD";
isConsecutive(s);
}
public static boolean isConsecutive(String s){
boolean letters;
letters = false;
int counter = 0;
String newS = s.toLowerCase();
for (int i = 0; i < newS.length() - 1; i++){
if (newS.charAt(i) - newS.charAt(i+1) == 1){
return true;
} else if (newS.charAt(i) - newS.charAt(i+1) == -1) {
return true;
}
}
return letters;
}
}
for (int i = 0; i < newS.length() - 1; i++){
if (newS.charAt(i) - newS.charAt(i+1) == 1){
return true;
} else if (newS.charAt(i) - newS.charAt(i+1) == -1) {
return true;
}
this is not what you're after.
You don't want to return true from within the for loop. Not unless you find that the order is not maintained. Else you'll return too early. On the other hand returning false is OK, again if you find that the order is in fact off.
You don't want to check if char - otherchar == 1 or -1 as that's too restrictive. You want to look at > 0 or < 0.
You're not doing anything with the return value. If you want to see it on the console, do System.out.println(isConsecutive(s));. That's why "nothing is happening". It's running properly as you wrote it; it just doesn't produce any visible output.
Just replace last line from main method with System.out.println(isConsecutive(s));. This should work.
You are not printing anything, try System.out.println(isConsecutive(s));

Password Verifier Issue

Edit: This is probably very bad code in the PasswordVerifier.Java
I'm doing a password verifier that checks if the entered password is at least 6 characters long, has an Uppercase letter, lowercase letter, and a digit.
I think I have the logistics of it somewhat correct, but for some reason my program isn't going to the next prompt. It asks me for my password and then hangs up and doesn't tell me whether my password is valid or not. I'm thinking that my for loops are correct so I don't know what my issue is.
PasswordVerifier.Java
import java.util.*;
public class PasswordVerifier{
//field
private static int MIN_PASSWORD_LENGTH = 6;
//methods
public static boolean isValid(String str){
boolean valid = false;
PasswordVerifier pass = new PasswordVerifier();
if(pass.hasUpperCase(str)|| pass.hasLowerCase(str) || pass.hasDigit(str)){
valid = true;
}
if (str.length() < 6){
valid = false;
}
return valid;
}
//UpperCase Boolean check
private boolean hasUpperCase(String str){
boolean valid = false;
int i = 0;
while (i < str.length()){
if (Character.isUpperCase(str.charAt(i)))
valid = true;
}
i++;
return valid;
}
//Lowercase Boolean Check
private boolean hasLowerCase(String str){
boolean valid = false;
int i = 0;
while (i < str.length()){
if (Character.isLowerCase(str.charAt(i)))
valid = true;
}
i++;
return valid;
}
//Number boolean check
private boolean hasDigit(String str){
boolean valid = false;
int i = 0;
while (i < str.length()){
if ((Character.isDigit(str.charAt(i))))
valid = true;
}
i++;
return valid;
}
}
PasswordDemo.Java
import javax.swing.JOptionPane;
public class PasswordDemo{
public static void main(String[] args){
String input; //To hold the user's input
input = JOptionPane.showInputDialog("Enter a Password");
if (PasswordVerifier.isValid(input)){
JOptionPane.showMessageDialog(null, "Valid Password");
}
else{
JOptionPane.showMessageDialog(null, "invalid Password, try again.");
}
}
}
Your while loops never increment i, because you placed i++ just past the end of the loop. The result is an infinite loop and the "hanging" you describe.
E.g. replace
while (i < str.length()){
if (Character.isUpperCase(str.charAt(i)))
{
valid = true;
// Added break because we found an uppercase letter already.
break;
}
i++; // Inside the while loop.
}
You'll need to make a similar change to each of your while loops.
Additionally, if you want to enforce all 3 provisions, don't use the logical-OR operator ||, use logical-and, &&:
if (pass.hasUpperCase(str) && pass.hasLowerCase(str) && pass.hasDigit(str)) {
valid = true;
}
That will make sure that the password has an uppercase letter and it has a lowercase letter and it has a digit.
I think your problem is that you are counting i++ outside the while loop.
Put it in the while like this:
private boolean hasUpperCase(String str){
boolean valid = false;
int i = 0;
while (i < str.length()){
if (Character.isUpperCase(str.charAt(i)))
valid = true;
i++;
}
return valid;
}
This is the problem in every while loop you got.
Right now you're making three passes through the password in order to verify the three character conditions - you can condense this down to one pass. In addition, you're checking the password's length last - you should check this first, as it's the fastest condition to verify.
public static boolean isValid(String str) {
if(str.length() < 6) return false;
int i = 0;
boolean hasDigit = false;
boolean hasLower = false;
boolean hasUpper = false;
while(i < str.length() && !hasDigit && !hasLower && !hasUpper) {
if(Character.isDigit(str.charAt(i))) {
hasDigit = true;
} else if(Character.isLowerCase(str.charAt(i))) {
hasLower = true;
} else if(Character.isUpperCase(str.charAt(i))) {
hasUpper = true;
}
i++;
}
return hasDigit && hasUpper && hasLower;
}
In your case the performance gain is probably negligible, but bear this in mind for the future when you may be dealing with more than three conditions and a string (or whatever) with a length much greater than six.

Categories

Resources