I have a problem that requires at least 2 uppercase letters, at least 2 lowercase letters and 2 digits.
Here is the exact problem:
Write an application that prompts the user for a password that contains at least two uppercase letters, at least two lowercase letters, and at least two digits. After a password is entered, display a message indicating whether the user was successful or the reason the user was not successful.
For example, if the user enters "Password" your program should output:
Your password was invalid for the following reasons:
uppercase letters
digits
If a user enters "P4SSw0rd", your program should output:
valid password
Here is my coding so far, I am having the problem of including output lines. For example, if someone doesn't have 2 capital letters AND doesn't have 2 letters. When writing 1 letter, it doesn't include both failures in the output.
import java.util.Scanner;
public class ValidatePassword {
public static void main(String[] args) {
String inputPassword;
Scanner input = new Scanner(System.in);
System.out.print("Password: ");
inputPassword = input.next();
System.out.println(PassCheck(inputPassword));
System.out.println("");
}
public static String PassCheck(String Password) {
String result = "Valid Password";
int length = 0;
int numCount = 0;
int capCount = 0;
for (int x = 0; x < Password.length(); x++) {
if ((Password.charAt(x) >= 47 && Password.charAt(x) <= 58) || (Password.charAt(x) >= 64 && Password.charAt(x) <= 91) ||
(Password.charAt(x) >= 97 && Password.charAt(x) <= 122)) {
} else {
result = "Password Contains Invalid Character!";
}
if ((Password.charAt(x) > 47 && Password.charAt(x) < 58)) {
numCount++;
}
if ((Password.charAt(x) > 64 && Password.charAt(x) < 91)) {
capCount++;
}
length = (x + 1);
}
if (numCount < 2) {
result = "Not Enough Numbers in Password!";
}
if (capCount < 2) {
result = "Not Enough Capital Letters in Password!";
}
if (length < 2) {
result = "Password is Too Short!";
}
return (result);
}
}
If I understand correctly what you want to do is when you enter e.g "Password" you don't have 2 capital letters and 2 digits so your output should looks like:
"Not Enough Numbers in Password! Not Enough Capital Letters in Password!".
I suggest 2 solutions:
If you want to add one String to another use + because you overwrite first result value with another. But this is not best solution because every time you add value to String you create new String on String pool. More information here:
https://stackoverflow.com/a/1553110/6003541
result += "Password is Too Short!";
or
result = result + "Password is Too Short!";
I suggest to use StringBuilder. Use method "append" to add your result and at the end return toString() value of StringBuilder object.
StringBuilder sb = new StringBuilder();
if (numCount < 2) {
sb.append("Not Enough Numbers in Password!");
sb.append(System.getProperty("line.separator"));
}
if (capCount < 2) {
sb.append("Not Enough Capital Letters in Password!");
sb.append(System.getProperty("line.separator"));
}
if (length < 2) {
sb.append("Password is Too Short!");
}
return sb.toString();
Related
I'm new at Java, and my first assignment is building a password validator. I'm not sure if it's the operators or the way I set up the strings. I can't seem to get the validation right. Also, how do I Validate special characters (!%$#...) without using regex.
import java.util.Scanner;
public class Password {
public static void main(String[] args) {
final int MAX=12;
final int MIN= 7;
final int MIN_Uppercase=1;
final int MIN_Lowercase=1;
final String SPECIAL="!";
int maxEl=0;
int minEl=0;
int upperCount=0;
int lowerCount=0;
String specialX = "!";
// Print a message asking the user to input a password via the console
System.out.println("The password must contain:\r\n"
+ " At least one lowercase letter\r\n"
+ " At least one uppercase letter\r\n"
+ " At least minimum 7 characters\r\n"
+ " At least maximum 12 characters\r\n"
+ " An exclamation point: !"
+ "Please enter a password: ");
//Receive the input via the console
Scanner scan = new Scanner(System.in);
String password = scan.nextLine();
int passwordLen = password.length();
//Check if there is at least one lower case letter
for (int i = 0; i < passwordLen; i++ ) {
char chr = password.charAt(i);
//Check if there is at least one upper case letter
if (Character.isUpperCase(chr))
upperCount++;
//Check if there is at least one lower case letter
else if (Character.isLowerCase(chr))
lowerCount++;
//Check if there are no more than 12 characters
else if (Character.isDigit(chr))
maxEl++;
//Check if there are at least 7 characters
else if (Character.isDigit(chr))
minEl++;
}
//If the password is valid, print "Password valid and accepted"
if(upperCount < MIN_Uppercase
&& lowerCount < MIN_Lowercase
&& maxEl < MAX
&& minEl < MIN
&& specialX !="!")
System.out.println("Password valid and\r\n"+ "accepted");
// If the password isn’t valid, print "Error"
else {
System.out.println("Error! ");
}
}
}
So the code is working fine however the number of attempts it takes to crack the 5 letter password is incorrect. I've tried fixing things however it's always giving me 3 digits. The number of attempts should be much higher.
Here's my code:
import java.util.Scanner;
import java.util.Random;
class Main {
public static void main(String[] args) {
// Letters for the random generated password
// Variables
String letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
Random order = new Random();
int PASSWORD = letters.length();
// While statement to allow user to keep generating passwords
while (true) {
String password = "";
Scanner input = new Scanner(System.in);
// Print/menu
System.out.println("Press 1 to generate a random password");
// Takes user input
int UserOption = input.nextInt();
// If user input equals 1
if (UserOption == 1) {
// Generate a 5-character passwords from the letters in the String
for (int i = 0; i < 5; i++) {
password = password + letters.charAt(order.nextInt(PASSWORD));
}
System.out.println(password);
cracking(5, password, letters, 0, "");
}
// If user input is anything except 1
else {
// Print error
System.out.println("Error");
}
}
}
//Method for cracking password
private static int cracking(int length, String password, String characters, int tries, String tryPass) {
System.out.println(length);
if (length == 0) {
System.out.println("It took " + tries + " tries to crack the password");
return 0;
}
for (int i = 0; i < characters.length(); i++) {
if (password.charAt(length-1) == characters.charAt(i)) {
tryPass = tryPass + characters.charAt(i);
break;
}
tries++;
}
cracking((length-1), password, characters, tries, tryPass);
return 0;
}
}
The length of the character set you are using is 62. The last character in the letters is 0, so the number of tries that would be required to match 0 is 61 tries.
So even if the randomly generated 5 letter password contains 00000 (all are the last characters in your character set.), the total number of tries would be 61*5, which is 305. So the output would never be greater than this value.
Hence, this code would never return a value much higher than a 3-digit number. (I am assuming that you expected 4 or 5 digit numbers). Also, the maximum value it could return is 305.
If you need the number of tries to be higher, then increase the password length.
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;
}
}
I have the following problem:
Today, everyone comes up with some clever phrase so you can remember
their phone number. You have been given the task to decipher these
phrases and find out what numbers you need to dial in order to contact
these places.
Description: You input will be series of letters, numbers and dashes. You will need to determine the number that the input sequence
represents in regular three - dash- four format (see example output).
You will also need to determine if the resulting number is a valid
number (seven digits) or if there is a number in the input at all.
Input: All letters will be in uppercase. The input string may be up to 25 characters long.
Output: A single line of output is all that is needed either printing the phone number, if the number is not a valid number or if
there is no number at all.
Translation Key ABC = 2 DEF = 3 GHI = 4 JKL = 5 MNO = 6 PRS = 7 TUV = 8 WXY = 9 Numbers will be as themselves and ignore all Q, Z
and dashes. Example Input: ITS-EASY Example Output : 487-3279
Example Input: ---2---3---TS-4 Example Output : Not a valid number.
Example Input: QZ---I-M-A-TEST Example Output : 462-8378 Example
Input: ---------- Example Output : No phone number.
I'm having trouble separating the dashes and unnecessary letters from the actual phrase that translates to the phone number. This is my program so far:
public static void main(String[] args) {
String cleverPhrase = getCleverPhrase("Input the phrase you use to remember a specific phone number (Max 25 characters allowed): ");
checkPhrase(cleverPhrase);
}
public static String getCleverPhrase(String prompt) {
String input;
System.out.print(prompt);
input = console.nextLine();
return input;
}
public static String checkPhrase(String cleverPhrase) {
int len = cleverPhrase.length();
String output = "";
do {
for(int i = 0; i <= len; i++) {
char current = cleverPhrase.charAt(i);
if (Character.isLetter(current)) {
String newCurrent = Character.toString(current);
if (newCurrent.equals('Q') || newCurrent.equals('Z')) {
}
}
}
} while ()
}
As you can see, I haven't made much progress. I don't know how to get the program to pick out the unnecessary letters and dashes and return just the letters that form the number. Could someone help me?
Check the following code..
public static String checkPhrase(String cleverPhrase) {
int len = cleverPhrase.length();
String output = "";
for (int i = 0; i <= len; i++) {
char current = cleverPhrase.charAt(i);
if (Character.isLetter(current)) {
if (current == 'A' || current == 'B' || current == 'C') {
output += "2";
} else if (current == 'D' || current == 'E' || current == 'F') {
output += "3";
} else if (...) {
....
}
}
if(output.length()==3){
output += "-";
}
}
if(output.isEmpty()){
output = "No phone number";
}else if(output.length()!=8){
output = "Not a valid number";
}
return output;
}
You can extend else-if for all other combinations of numbers. You don't have to check for invalid characters like - or Q or Z. The output variable will be get edited if it goes inside a if statement.
This method will be very handy in your case. Thanks to that you can replace this
if (current == 'A' || current == 'B' || current == 'C')
...
} else if (current == 'D' || current == 'E' || current == 'F') {
...
with this
StringUtils.replaceChars(input, "ABCDEF", "222333")
You can also get rid of all non-numbers simply by output.replaceAll( "[^\\d]", "" ). At the end, you can add the dash in a specific position and check if the number is valid.
To strip out the unwanted characters in your string, have a look at String.replaceAll
I'm having a huge problem here. Basically what i have to do is have a user enter a number... the program then takes the number, reads if it's negative or positive. If negative it sets the previously false negval to true and moves on. it then reads the number again, checking for leading zeros, if there are any it removes them. It then takes what is left and checks to see if the string is less than the max amount of characters aloud, if it is then it loops to count the spaces, while it counts the spaces it also makes sure they are digits . if the string is bigger than the allowed amount of characters the program stops checks and prints a 0
my problem is that it keeps jumping to the 0 output even though the string length is a valid length
here is what i have.
String snum;
System.out.print("Please enter a number here : ");
snum = console.next();
System.out.println(getIntnum(" The number entered was: "+snum));
Other generic stuff
final String maxInt = "2147483648";
final String minInt = "-2147483648";
boolean negval = false;
int n;
int count;
int num = 1;
int value;
if(snum.charAt(0) == '-' || snum.charAt(0) == '+')
{
if(snum.charAt(0) == '-')
{
negval = true;
}
else
{
snum = snum.substring(1, snum.length());
}
}
while (snum.charAt(0) == '0')
{
snum = snum.substring(1, snum.length());
}
n = snum.length( );
if (n < 10)
{
count = 0;
if (count < n)
{
if (Character.isDigit(snum.charAt(count)))
count++;
}
}
else
{
num = 0;
}
if(maxInt.compareTo(snum) >= 0 && minInt.compareTo(snum) <= 0)
{
num = Integer.parseInt(snum);
}
if(negval == true)
{
num = num * -1;
}
value = num;
return value;
}
}
You are comparing Strings which don't work the same way as comparing numbers. For example, "10" < "2" because '1' < '2' and this means that "-1" < "-2147483648" and "3" > "2147483647"
It's difficult to suggest what you should do instead as it's not clear to me why you are doing half of the code you have e.g. Can you say how your code is different from
try {
return Integer.parseInt(s);
} catch (NumberFormatException ignored) {
return 0;
}
Your main problem is that you're using a string comparison to compare numbers. Also, since you already know that the number is positive, there's not much point comparing it to minInt. Lastly, you have the wrong value for maxInt.
Simply use Integer.parseInt(snum)
final String maxInt = "2147483648";
MAX_INT is 2147483647.
Second of all, do not use String comparison to compare numbers. Use it like this:
if (Integer.parseInt(maxInt) >= Integer.parseInt(snum)) {
num = Integer.parseInt(snum);
}