This is the assignment I'm working on right now...
Implement a program that reads in a user password and verifies it meets the following criteria:
Is atleast 8 characters long
Contains atleast 1 lower letter character
Contains atleast 1 upper letter character
Contains atleast 1 numeric digit
Contains atleast 1 special character from the set: !##$%^&*
Does not contain the word “and” or the word “end”
Output a string that prompts the user for a password and include the requirements
above in your output.
Output a string that states valid or invalid. If invalid, state which rule above has not been met.
Utilize the following functionality:
indexOf
Looping structure
charAt()
isDigit()
isUpperCase()
isLowerCase()
and any additional functionality needed
The tricky part to me is that it has to return with all of the things that are missing. Like if I put in a password that says password, it should come back and tell me "you're missing an upper case, a digit, and a special character"
I have a start, but I'm really confused on how to get it to return something to me.
This is what i have so far
/********************************************
This program will test a password for:
8 characters
1 upper case
1 lower case
1 numeric digit
1 special character from the set !##$%^&*
and make sure it doesn't contain AND or END
If the password complies, it will return a valid answer
If not, it will tell the user what they need to do.
*********************************************/
import java.util.Scanner;
public class YoungAmyProg5
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String input;
//input password
System.out.println("Enter a password that follows these rules:\n Is at least 8 characters long\n Contains at least 1 lower case letter\n Contains at least 1 upper case letter\n Contains at least 1 numeric digit\n Contains at least 1 special character from the set: ! ##$%^&*\n Does NOT contain the word "and" or the word "end": ")
input= in.nextLine ();
//Put through string and reply
if
public static boolean isSecurePassword(String password) {
int lengthPassword = password.length();
if (lengthPassword >= 8 ) {
return false;
}
boolean hasUppercase = false; //uppercase
boolean hasLowecase = false; //lowercase
boolean hasDigit = false; //digit
int specialChar = input.indexOf('!', '#', '#', '$', '%', '^', '&', '*'); //special character
int word = input.indexOf ('and', 'end'); //and or end
for (int i = 0; i < lengthPassword; i++) {
char ch = password.charAt(i);
if (Character.isUpperCase(ch) ) {
hasUppercase = true;
}
if (Character.isLowerCase(ch) ) {
hasLowercase = true;
}
if (Character.isDigit(ch) ) {
hasDigit = true;
}
if (specialChar>0) {
specialChar = true;
}
if (word>0) {
word = true;
}
Instead of setting variables, you could also create a list that stores missing things and a boolean too check if error occured:
List<String> missing = new ArrayList<String>();
boolean verified = true;
And inside your if-statements, if somethíng is wrong, set verified to false and add a string like 'an upper case letter' to the list.
if( <password does NOT contain an upper case letter> )
missing.add("an upper case letter");
verified = false;
}
After all if-statements just check if verified is true, if not generate a string and add all strings from the missing list to it. (Generate the sentence)
(I know this will end in a somewhat long code and that it is not too efficient)
Maybe you can think in another way: when you find a reqiurement is violated, return false; if finally turns out no violation, return true.
Related
I recently came across this solution to writing a program that capitalizes each word in a string and I'm trying really hard to understand it, but I can't get over one hurdle.
public class test {
public static void main(String[] args) {
// create a string
String message = "everyone loves java";
// stores each characters to a char array
char[] charArray = message.toCharArray();
boolean foundSpace = true;
for(int i = 0; i < charArray.length; i++) {
// if the array element is a letter
if(Character.isLetter(charArray[i])) {
// check space is present before the letter
if(foundSpace) {
// change the letter into uppercase
charArray[i] = Character.toUpperCase(charArray[i]);
foundSpace = false;
}
}
else {
// if the new character is not character
foundSpace = true;
}
}
// convert the char array to the string
message = String.valueOf(charArray);
System.out.println("Message: " + message);
}
I understand everything in this code except for how it checks if the previous character was a space. The comment says it does this with the if(foundSpace) statement, but I don't see any reason why that would work since it's never specified that it's looking for a space. Any pointers in the right direction would be appreciated
Edit: Thanks for everyone’s answers, I think I finally get it now!
Look at the code inside the loop, stripped down a bit:
for(int i = 0; i < charArray.length; i++) {
if(Character.isLetter(charArray[i])) {
// check space is present before the letter
if(foundSpace) {
// Some code.
foundSpace = false;
}
// Here, foundSpace is false.
} else {
foundSpace = true;
}
}
The code doesn't care about what your variables or methods are called: it's checking if the character meets some criterion (Character.isLetter), and afterwards it has recorded whether or not the character met that criterion (in foundSpace).
This means that foundSpace contains whether the previous character met that criterion, and allows you to decide to do something on the current character based on what the previous one was: in your case, uppercase that character if the previous character didn't meet the criterion.
foundSpace is initially set to true, which means that the loop treats a string which starts with a letter as if there was a space before it, and so that will be capitalized.
Really, there is just a mismatch between the criterion used, and the name of the variable:
If the criterion should be "is it whitespace", use Character.isWhitespace as your criterion, and keep the flag name as foundSpace;
If the criterion really is "is it a letter", use Character.isLetter as your criterion, and name the flag foundLetter (and invert its sense, so check if (!foundLetter) etc, because it's easier to deal with "positive" checks (if (foundLetter)) rather than "negative" checks (if (!foundLetter))).
foundSpace is only set to false if the condition:
(Character.isLetter(charArray[i]))
is triggered.
If the condition is not triggered, aka if the character is not a letter, then foundSpace will be set to True.
This means that anything that is not a letter will set foundSpace equal to true.
As Silvio pointed out, this includes other non space characters such as 1, $, and ".
It would be better instead of checking if the character is a letter, to instead check to see if charArray[i] is equal to a space.
Like so:
boolean foundSpace = Character.isWhitespace(charArray[i])
More info about the Character class can be found below:
https://www.geeksforgeeks.org/character-equals-method-in-java-with-examples/
The code you've shown could have some undesirable side effects - especially if foundSpace is relied upon later on - because it could potentially lead you to believe that a space exists in a word, when it's not a space at all but rather a character that isn't a letter like "$".
In the context of your entire program, this looks like:
public class test {
public static void main(String[] args) {
// create a string
String message = "everyone loves java";
// stores each characters to a char array
char[] charArray = message.toCharArray();
boolean foundSpace = true;
for(int i = 0; i < charArray.length; i++) {
if(Character.isWhitespace(charArray[i])){
foundSpace = true;
}
else{
foundSpace = false;
}
// if the array element is a letter
if(Character.isLetter(charArray[i])) {
// check space is present before the letter
if(foundSpace) {
// change the letter into uppercase
charArray[i] = Character.toUpperCase(charArray[i]);
}
}
else {
// if the new character is not character
// delete this condition if you don't plan to use it
}
}
// convert the char array to the string
message = String.valueOf(charArray);
System.out.println("Message: " + message);
}
Some edits made to the code to fix compilation errors, thanks to those in the comments for your suggestions.
I have a task to write a return type method which takes String as an argument and returns boolean. If the String matches with the requirements it returns true else false.
So it should not have any space, and more then 1 '#'and format must be 2>chars#2>chars.2>chars so it should be xyz#xyz.com is true but if any part of it less then 3 it should return to false. I checked so many forums but all i can find regex and we didn't learn anything about it. I could able to do this much but i just couldn't figure out how can i specifically set length of each part and set it as true or false. I'm missing so many and this is all i able to complete;
public static boolean emailAddress(String str) {
if (str.contains(" "))
return false;
boolean flag = true;
if(str3.length()> 11)
for (int i = 0; i < str3.length(); i++) {
for (int j = i + 1; j < str3.length(); j++) {
if (str3.charAt(i) == str3.charAt(j)) {
flag = false;
break;
}
}
if(flag)
return true;
}
return false;
}
This is how I would approach it:
public static boolean isEmailAddress(String str)
{
if(str.trim().equals("")) // Checking if it is an empty string
{
return false;
}
boolean flag = true;
int atIndex = str.indexOf("#"); // Get the index of #
if (atIndex == -1)
{
return false;
}
// Slice your email str and get only the characters before the #
// Check whether the length and the characters are as you want them.
// Do the same thing about the string between # and .
// and then do the same thing about the sliced string after .
}
Check substring() and indexOf().
For anyone who needs it.
This should be one of the Regex to match your requirement:
[a-zA-Z_0-9]{2,}#[a-zA-Z_0-9]{2,}\.[a-zA-Z_0-9]{2,}
[a-zA-Z_0-9] it requires one of the characters, from a-z,A-Z or 0-9
{2,} it requires two or more from one of the characters inside.
A few hints instead of complete solution:
Check if the input string...
has # and . (there could be two or three period's as some domain uses .co.in)
does not have any white spaces (' ')
does not start with special characters ('#', '^')
If possible, do not check for length of each part, as sometimes .in also valid domain.
SO i made a CharSequence[] array with all the two consecutive uppercase letters. Why is this code not returning the correct values?
public static boolean containConsecCaps(String passw)
{
CharSequence[] consec = {"AA","AB","AC","AD","AE","AF", ... "ZZ"};
boolean contain = false;
String pass = passw;
for (int i = 0; i <= 675; i++)
{
contain = pass.contains(consec[i]);
if (contain == true)
break;
}
return contain;
}
and in the main string, this syntax:
while (consec != false)
{
//Consec.setPassword(password.getPassword());
consec = Consec.containConsecCaps(password.getPassword());
if (consec == false)
break;
else
password.setPassword(reader.readLine("Error. Please enter a password with no consecutive letters: "));
}
now everything else in the three classes work. This is the only problem and it seems to get stuck in the else. Why is it not testing all of the array char's then returning true or not?
It gets stuck in a loop if i enter: AApassword.1 , which fits all the other criteria, except the two consecutive capitals. So then i enter: aApassword.1 , which should fit ALL of the criteria, but it still prints out the else statement, instead of breaking the while loop.
Can anyone help me?
This Java code is giving me trouble:
String word = <Uses an input>
int y = 3;
char z;
do {
z = word.charAt(y);
if (z!='a' || z!='e' || z!='i' || z!='o' || z!='u')) {
for (int i = 0; i==y; i++) {
wordT = wordT + word.charAt(i);
} break;
}
} while(true);
I want to check if the third letter of word is a non-vowel, and if it is I want it to return the non-vowel and any characters preceding it. If it is a vowel, it checks the next letter in the string, if it's also a vowel then it checks the next one until it finds a non-vowel.
Example:
word = Jaemeas then wordT must = Jaem
Example 2:
word=Jaeoimus then wordT must =Jaeoim
The problem is with my if statement, I can't figure out how to make it check all the vowels in that one line.
Clean method to check for vowels:
public static boolean isVowel(char c) {
return "AEIOUaeiou".indexOf(c) != -1;
}
Your condition is flawed. Think about the simpler version
z != 'a' || z != 'e'
If z is 'a' then the second half will be true since z is not 'e' (i.e. the whole condition is true), and if z is 'e' then the first half will be true since z is not 'a' (again, whole condition true). Of course, if z is neither 'a' nor 'e' then both parts will be true. In other words, your condition will never be false!
You likely want &&s there instead:
z != 'a' && z != 'e' && ...
Or perhaps:
"aeiou".indexOf(z) < 0
How about an approach using regular expressions? If you use the proper pattern you can get the results from the Matcher object using groups. In the code sample below the call to m.group(1) should return you the string you're looking for as long as there's a pattern match.
String wordT = null;
Pattern patternOne = Pattern.compile("^([\\w]{2}[AEIOUaeiou]*[^AEIOUaeiou]{1}).*");
Matcher m = patternOne.matcher("Jaemeas");
if (m.matches()) {
wordT = m.group(1);
}
Just a little different approach that accomplishes the same goal.
Actually there are much more efficient ways to check it but since you've asked what is the problem with yours, I can tell that the problem is you have to change those OR operators with AND operators. With your if statement, it will always be true.
So in event anyone ever comes across this and wants a easy compare method that can be used in many scenarios.
Doesn't matter if it is UPPERCASE or lowercase. A-Z and a-z.
bool vowel = ((1 << letter) & 2130466) != 0;
This is the easiest way I could think of. I tested this in C++ and on a 64bit PC so results may differ but basically there's only 32 bits available in a "32 bit integer" as such bit 64 and bit 32 get removed and you are left with a value from 1 - 26 when performing the "<< letter".
If you don't understand how bits work sorry i'm not going go super in depth but the technique of
1 << N is the same thing as 2^N power or creating a power of two.
So when we do 1 << N & X we checking if X contains the power of two that creates our vowel is located in this value 2130466. If the result doesn't equal 0 then it was successfully a vowel.
This situation can apply to anything you use bits for and even values larger then 32 for an index will work in this case so long as the range of values is 0 to 31. So like the letters as mentioned before might be 65-90 or 97-122 but since but we keep remove 32 until we are left with a remainder ranging from 1-26. The remainder isn't how it actually works, but it gives you an idea of the process.
Something to keep in mind if you have no guarantee on the incoming letters it to check if the letter is below 'A' or above 'u'. As the results will always be false anyways.
For example teh following will return a false vowel positive. "!" exclamation point is value 33 and it will provide the same bit value as 'A' or 'a' would.
For starters, you are checking if the letter is "not a" OR "not e" OR "not i" etc.
Lets say that the letter is i. Then the letter is not a, so that returns "True". Then the entire statement is True because i != a. I think what you are looking for is to AND the statements together, not OR them.
Once you do this, you need to look at how to increment y and check this again. If the first time you get a vowel, you want to see if the next character is a vowel too, or not. This only checks the character at location y=3.
String word="Jaemeas";
String wordT="";
int y=3;
char z;
do{
z=word.charAt(y);
if(z!='a'&&z!='e'&&z!='i'&&z!='o'&&z!='u'&&y<word.length()){
for(int i = 0; i<=y;i++){
wordT=wordT+word.charAt(i);
}
break;
}
else{
y++;
}
}while(true);
here is my answer.
I have declared a char[] constant for the VOWELS, then implemented a method that checks whether a char is a vowel or not (returning a boolean value). In my main method, I am declaring a string and converting it to an array of chars, so that I can pass the index of the char array as the parameter of my isVowel method:
public class FindVowelsInString {
static final char[] VOWELS = {'a', 'e', 'i', 'o', 'u'};
public static void main(String[] args) {
String str = "hello";
char[] array = str.toCharArray();
//Check with a consonant
boolean vowelChecker = FindVowelsInString.isVowel(array[0]);
System.out.println("Is this a character a vowel?" + vowelChecker);
//Check with a vowel
boolean vowelChecker2 = FindVowelsInString.isVowel(array[1]);
System.out.println("Is this a character a vowel?" + vowelChecker2);
}
private static boolean isVowel(char vowel) {
boolean isVowel = false;
for (int i = 0; i < FindVowelsInString.getVowel().length; i++) {
if (FindVowelsInString.getVowel()[i] == vowel) {
isVowel = true;
}
}
return isVowel;
}
public static char[] getVowel() {
return FindVowelsInString.VOWELS;
}
}
I would like to find an efficient way (not scanning the String 10,000 times, or creating lots of intermediary Strings for holding temporary results, or string bashing, etc.) to write a method that accepts a String and determine if it meets the following criteria:
It is at least 2 characters in length
The first character is uppercased
The remaining substring after the first character contains at least 1 lowercased character
Here's my attempt so far:
private boolean isInProperForm(final String token) {
if(token.length() < 2)
return false;
char firstChar = token.charAt(0);
String restOfToken = token.substring(1);
String firstCharAsString = firstChar + "";
String firstCharStrToUpper = firstCharAsString.toUpperCase();
// TODO: Giving up because this already seems way too complicated/inefficient.
// Ignore the '&& true' clause - left it there as a placeholder so it wouldn't give a compile error.
if(firstCharStrToUpper.equals(firstCharAsString) && true)
return true;
// Presume false if we get here.
return false;
}
But as you can see I already have 1 char and 3 temp strings, and something just doesn't feel right. There's got to be a better way to write this. It's important because this method is going to get called thousands and thousands of times (for each tokenized word in a text document). So it really really needs to be efficient.
Thanks in advance!
This function should cover it. Each char is examined only once and no objects are created.
public static boolean validate(String token) {
if (token == null || token.length() < 2) return false;
if (!Character.isUpperCase(token.charAt(0)) return false;
for (int i = 1; i < token.length(); i++)
if (Character.isLowerCase(token.charAt(i)) return true;
return false;
The first criteria is simply the length - this data is cached in the string object and is not requiring traversing the string.
You can use Character.isUpperCase() to determine if the first char is upper case. No need as well to traverse the string.
The last criteria requires a single traversal on the string- and stop when you first find a lower case character.
P.S. An alternative for the 2+3 criteria combined is to use a regex (not more efficient - but more elegant):
return token.matches("[A-Z].*[a-z].*");
The regex is checking if the string starts with an upper case letter, and then followed by any sequence which contains at least one lower case character.
It is at least 2 characters in length
The first character is
uppercased
The remaining substring after the first character contains
at least 1 lowercased character
Code:
private boolean isInProperForm(final String token) {
if(token.length() < 2) return false;
if(!Character.isUpperCase(token.charAt(0)) return false;
for(int i = 1; i < token.length(); i++) {
if(Character.isLowerCase(token.charAt(i)) {
return true; // our last criteria, so we are free
// to return on a met condition
}
}
return false; // didn't meet the last criteria, so we return false
}
If you added more criteria, you'd have to revise the last condition.
What about:
return token.matches("[A-Z].*[a-z].*");
This regular expression starts with an uppercase letter and has at least one following lowercase letter and therefore meets your requirements.
To find if the first character is uppercase:
Character.isUpperCase(token.charAt(0))
To check if there is at least one lowercase:
if(Pattern.compile("[a-z]").matcher(token).find()) {
//At least one lowercase
}
To check if first char is uppercase you can use:
Character.isUpperCase(s.charAt(0))
return token.matches("[A-Z].[a-z].");