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;
}
Related
is this the most efficient method to determine that there is a minimum of two unique characters in a String? Should I have used arrays to hold the characters? Thank you
public static Boolean checkPW(String pw) {
Boolean validLower = false, validUpper = false, validNumber = false;
char lowerCompare = '0', upperCompare = '0', numberCompare = 'a';
for(int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(character >= 'a' && character <= 'z') {
if(lowerCompare == '0')
lowerCompare = character;
else if(lowerCompare != character)
validLower = true;
} // lower-case if END
} // for-loop END
if(validLower)
return true;
else
return false;
} // checkPW END
If I had to do this in Java, in production, I might just use a set here:
String input = "abcdefgzz";
char[] letters = input.toCharArray();
Set<Character> set = new HashSet<>();
boolean valid = false;
for (char letter : letters) {
set.add(letter);
if (set.size() > 1) {
valid = true;
break;
}
}
if (valid) {
System.out.println("Minimum of two unique letters");
}
else {
System.out.println("Only one unique letter");
}
is this the most efficient method to determine that there is a minimum of two unique characters in a String?
No. The loop continues to run after 2 unique valid characters are found, which is unnecessary. It could stop immediately, and then it will be more efficient. Consider for example the string "ab" followed by a million characters. There's no need to go further than the first two.
Should I have used arrays to hold the characters?
The question is not clear. To make it meaningful, you would need to include reasoning for the benefits of both methods. And it's not clear what technique you're referring to.
It would be good to remove all the unnecessary variables from the program.
After fixing the inefficiency, and a bit of cleanup:
public static boolean checkPW(String pw) {
char first = '0';
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if ('a' <= character && character <= 'z') {
if (first == '0') {
first = character;
} else if (first != character)
return true;
}
}
}
return false;
}
I'd do this:
public static boolean checkPW(String pw) {
Character lowerCompare = null;
for (int position = 0; position < pw.length(); ++position) {
char character = pw.charAt(position);
if(Character.isLowerCase(c)) { // this handles non-ASCII lower case characters
if(lowerCompare == null) {
lowerCompare = character;
} else if(lowerCompare != character) {
return true;
}
}
}
return false;
}
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
public static boolean isValidNumber(String a1)
{
String x = ("0123456789");
boolean valid = false;
for (int i = 0; i < 4; i++) {
char c = a1.charAt(i);
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
valid = true;
}
else {
valid = false;
}
}
}
return valid;
}
The above method checks to see whether an input of a four character string is composed of the characters 0123456789. However, regardless of what the input is, the method always returns as false.
If I were to change the valid value in the else statement to true, the method would always return as true.
What is the error that I have made in this method?
As soon as you find a non matching character, break the loop otherwise the next matching character will set valid to true.
e.g. "123a456" is considered valid.
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
valid = true;
}
else {
valid = false;
break;
}
}
If for some reason you don't want to break the loop, you could keep an "invalid counter" and make sure that is 0 at the end.
Of course for what you are doing here, Integer.parseInt() might be your best bet ;-)
a String.equals method will check these two strings in a single statement if you are permitted to use that.
public static boolean isValidNumber(String a1)
{
String x = ("0123456789");
return x.equals(a1);
}
I would rewrite your function as given below,
String x = ("0123456789");
boolean valid = false;
for (int i = 0; i < 4; i++) {
char c = a1.charAt(i);
boolean isCharOK = false;
for (int j = 0; j < 10; j++) {
if ( c == x.charAt(j)) {
isCharOK = true;
break;
}
}
if (!isCharOK) {
valid = false;
break;
}
}
return valid;
John3136 is quite correct, but I would like to propose even better solution to your whole task:
final static String x = "0123456789";
public static boolean isValidNumber(String a1) {
for (int i = 0; i < a1.length(); ++i) {
if (x.indexOf(a1.charAt(i)) == -1) return false;
}
return true;
}
In short: the above code "looks up" every character in your parameter string a1 in the string composed of digits. If it can find it, continues. If it can't, it means a1 consist not only digits and returns false. If it passes through all a1 characters then it returns true :)
And as asked and described in the comments - handling of duplicate characters in argument string:
final static String x = "0123456789";
public static boolean isValidNumber(String a1) {
for (int i = 0; i < a1.length(); ++i) {
final char currentChar = a1.charAt(i);
if (x.indexOf(currentChar) == -1 || a1.indexOf(currentChar, i+1) != -1)
return false;
}
return true;
}
The function call a1.indexOf(currentChar, i+1) essentially checks if there is any duplicate character in the rest of the string (from position i+1 and farther). Which means if it will be able to find duplicate char, the method return false :) Hope this helps, here is more info on String.indexOf(int, int) function if you want:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int, int)
You can use this one liner function to check for validity of a String as Number using Regular Expression
public static boolean isValidNumber(String a1)
{
return a1.matches("[\\d]+");
}
Hope this helps.
I am trying to loop through a string and check each character if one of the characters is a number. If it is a number, I want to return it as true. I have a string "crash", though it returns it as true (that it has a number).
Here's what I have so far:
public boolean isNumber()
{
String newString = "crash";
boolean isNumber = true;
for (int i=0; i<newString.length(); i++)
{
if (Character.isDigit(newString.charAt(i)))
{
isNumber = true;
continue; // continue looping through the string. Go on to the next index.
// The character at index i is a number.
}
else
{
isNumber = false;
break; // terminate the for-loop and return it as false! It is not a number!
}
}
return isNumber;
}
I can't figure out what's wrong. My logic seems to be fine, but my coding isn't.
EDIT: I figured it out. Thanks for all your help!
I just ran that code and I get false, as expected. Please double-check that you’re running it correctly.
Here’s a simpler way to express that function, by the way:
public boolean isNumber(String string) {
for (int i = 0; i < string.length(); i++) {
if (!Character.isDigit(string.charAt(i))) {
return false;
}
}
return true;
}
Maybe I didn't understand you correctly... but since you're using the same variable "isNumber", and continuing when you get a positive match... the result you'll return will always be of the last character of the String, except when you get a non numeric character, in which case, you exit right away.
Do you want to check if the whole String is a number? Or if it contains a number?
Your code should work correctly, although I would probably use this instead:
public boolean isNumber(String newString)
{
for (int i=0; i != newString.length(); i++)
{
if (!Character.isDigit(newString.charAt(i)))
{
return false;
}
}
return true;
}
// a regex equivalent
public boolean isNumberRegex(String newString)
{
return newString.match("\\d+");
}
The method above checks if all characters are digits.
If I misunderstood your question and you want to check if any of the characters is a digit:
public boolean hasNumber(String newString)
{
for (int i=0; i != newString.length(); i++)
{
if (Character.isDigit(newString.charAt(i)))
{
return true;
}
}
return false;
}
// regex equivalent
public boolean hasNumberRegex(String newString)
{
return newString.match(".*\\d.*");
}
Well you can use Integer.parseInt("string") and catch the exception.
try {
int num = Integer.parseInt("string");
return true;
} catch (NumberFormatException nfe) {
return false;
}
Or another way with regEx:
if ("string".replaceAll("\\d+","").length() > 0) {
//false
} else {
//true
}
public static boolean isNumber(String str)
{
int len = str.length();
boolean isNumber = false;
for(int i = 0; i < len; i++)
{
if(Character.isDigit(str.charAt(i)))
return true;
}
return isNumber;
}
I think this code should work, but to my mind, setting a variable and then breaking just to return it is ugly. (I know other coders like this; IMHO they are wrong.) I also dislike introducing unnecessary test variables, like NullUserException's solution. I would just return directly.
[EDIT: This code is the same as Brockman's]
public boolean isNumber() /* Note: returns true for empty string */
{
String newString = "crash";
for (int i=0; i<newString.length(); i++)
{
if (!Character.isDigit(newString.charAt(i)))
{
return false; /* non-digit detected */
}
}
return true; /* all characters were digits */
}
The idea is to have a String read and to verify that it does not contain any numeric characters. So something like "smith23" would not be acceptable.
What do you want? Speed or simplicity? For speed, go for a loop based approach. For simplicity, go for a one liner RegEx based approach.
Speed
public boolean isAlpha(String name) {
char[] chars = name.toCharArray();
for (char c : chars) {
if(!Character.isLetter(c)) {
return false;
}
}
return true;
}
Simplicity
public boolean isAlpha(String name) {
return name.matches("[a-zA-Z]+");
}
Java 8 lambda expressions. Both fast and simple.
boolean allLetters = someString.chars().allMatch(Character::isLetter);
Or if you are using Apache Commons, [StringUtils.isAlpha()].
First import Pattern :
import java.util.regex.Pattern;
Then use this simple code:
String s = "smith23";
if (Pattern.matches("[a-zA-Z]+",s)) {
// Do something
System.out.println("Yes, string contains letters only");
}else{
System.out.println("Nope, Other characters detected");
}
This will output:
Nope, Other characters detected
I used this regex expression (".*[a-zA-Z]+.*"). With if not statement it will avoid all expressions that have a letter before, at the end or between any type of other character.
String strWithLetters = "123AZ456";
if(! Pattern.matches(".*[a-zA-Z]+.*", str1))
return true;
else return false
A quick way to do it is by:
public boolean isStringAlpha(String aString) {
int charCount = 0;
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (aString.length() == 0) {
return false; //zero length string ain't alpha
}
for (int i = 0; i < aString.length(); i++) {
for (int j = 0; j < alphabet.length(); j++) {
if (aString.substring(i, i + 1).equals(alphabet.substring(j, j + 1))
|| aString.substring(i, i + 1).equals(alphabet.substring(j, j + 1).toLowerCase())) {
charCount++;
}
}
if (charCount != (i + 1)) {
System.out.println("\n**Invalid input! Enter alpha values**\n");
return false;
}
}
return true;
}
Because you don't have to run the whole aString to check if it isn't an alpha String.
private boolean isOnlyLetters(String s){
char c=' ';
boolean isGood=false, safe=isGood;
int failCount=0;
for(int i=0;i<s.length();i++){
c = s.charAt(i);
if(Character.isLetter(c))
isGood=true;
else{
isGood=false;
failCount+=1;
}
}
if(failCount==0 && s.length()>0)
safe=true;
else
safe=false;
return safe;
}
I know it's a bit crowded. I was using it with my program and felt the desire to share it with people. It can tell if any character in a string is not a letter or not. Use it if you want something easy to clarify and look back on.
Faster way is below. Considering letters are only a-z,A-Z.
public static void main( String[] args ){
System.out.println(bestWay("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(isAlpha("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(bestWay("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
System.out.println(isAlpha("azAZpratiyushkumarsinghjdnfkjsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
}
public static boolean bettertWay(String name) {
char[] chars = name.toCharArray();
long startTimeOne = System.nanoTime();
for(char c : chars){
if(!(c>=65 && c<=90)&&!(c>=97 && c<=122) ){
System.out.println(System.nanoTime() - startTimeOne);
return false;
}
}
System.out.println(System.nanoTime() - startTimeOne);
return true;
}
public static boolean isAlpha(String name) {
char[] chars = name.toCharArray();
long startTimeOne = System.nanoTime();
for (char c : chars) {
if(!Character.isLetter(c)) {
System.out.println(System.nanoTime() - startTimeOne);
return false;
}
}
System.out.println(System.nanoTime() - startTimeOne);
return true;
}
Runtime is calculated in nano seconds. It may vary system to system.
5748//bettertWay without numbers
true
89493 //isAlpha without numbers
true
3284 //bettertWay with numbers
false
22989 //isAlpha with numbers
false
Check this,i guess this is help you because it's work in my project so once you check this code
if(! Pattern.matches(".*[a-zA-Z]+.*[a-zA-Z]", str1))
{
String not contain only character;
}
else
{
String contain only character;
}
String expression = "^[a-zA-Z]*$";
CharSequence inputStr = str;
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
{
//if pattern matches
}
else
{
//if pattern does not matches
}
Try using regular expressions: String.matches
public boolean isAlpha(String name)
{
String s=name.toLowerCase();
for(int i=0; i<s.length();i++)
{
if((s.charAt(i)>='a' && s.charAt(i)<='z'))
{
continue;
}
else
{
return false;
}
}
return true;
}
Feels as if our need is to find whether the character are only alphabets.
Here's how you can solve it-
Character.isAlphabetic(c)
helps to check if the characters of the string are alphabets or not.
where c is
char c = s.charAt(elementIndex);
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the https://www.nuget.org/packages/Extensions.cs package to your project.
Add "using Extensions;" to the top of your code.
"smith23".IsAlphabetic() will return False whereas "john smith".IsAlphabetic() will return True. By default the .IsAlphabetic() method ignores spaces, but it can also be overridden such that "john smith".IsAlphabetic(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphabetic().
To allow only ASCII letters, the character class \p{Alpha} can be used. (This is equivalent to [\p{Lower}\p{Upper}] or [a-zA-Z].)
boolean allLettersASCII = str.matches("\\p{Alpha}*");
For allowing all Unicode letters, use the character class \p{L} (or equivalently, \p{IsL}).
boolean allLettersUnicode = str.matches("\\p{L}*");
See the Pattern documentation.
I found an easy of way of checking a string whether all its digit is letter or not.
public static boolean isStringLetter(String input) {
boolean b = false;
for (int id = 0; id < input.length(); id++) {
if ('a' <= input.charAt(id) && input.charAt(id) <= 'z') {
b = true;
} else if ('A' <= input.charAt(id) && input.charAt(id) <= 'Z') {
b = true;
} else {
b = false;
}
}
return b;
}
I hope it could help anyone who is looking for such method.
Use StringUtils.isAlpha() method and it will make your life simple.