Recursion - Displaying wrong number of attempts - java

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.

Related

How to validate a special character like ! in a password in Java without using regex?

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! ");
}
}
}

How to split an input of numbers (student ID) from user to implement into formula

I'm having trouble with this beginner java program that was assigned to me, I'm completely new to java and I'm having a lot of trouble with this particular program. These are the instructions:
Your program should prompt users to enter an n-digit number as a student ID, and then display the
validity of the entered ID. You can assume n will be in the range of 6 and 10 inclusive. The checksum
digit is part of student ID. Your algorithm is to match the rightmost digit in the entered ID with the
computed checksum digit. If there is no match, then your program shall report the entered ID being
invalid.
For example, the entered ID 1234567 is invalid because the computed 7th digit is 1 (= (1 * (digit1) + 2 *
(digit 2) + 3 * (digit 3) + 4 * (digit 4) + 5 * (digit 5) + 6 * (digit 6)) % 10) and is different from the actual 7th digit which is
7. However, if the entered ID is 1234561 your program shall display a message of acceptance.
The first step I'm trying to do is to read each number from the user's input that doesn't have spaces, as if it were to have spaces. Then I'm trying to get each of those numbers assigned to the variable that is digit 1, digit 2, ... etc. to compute.
import java.util.Scanner;
public class H4_Ruby{
public static void main(String[] args){
// this code scans the the user input
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a student ID between 6-10 digits");
String nums = scan.nextLine();
String[] studentIdArray = nums.split(" ");
int[] studentID = new int [studentIdArray.length];
for (int i = 0; i < studentIdArray.length; i++)
{
studentID[i]= Integer.parseInt(studentIdArray[i]);
System.out.print(studentID[i] + ",");
}
}
That is my code so far...
You can't split by nums.split(" ") to get a String array. You already got a String Id from user without spaces.
So iterate through the String and keep calculating the sum of products with multiplier like below. I've added comments in the code itself.
public static void main(String[] args) {
// this code scans the the user input
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a student ID between 6-10 digits");
String nums = scan.nextLine();
int multiplier = 1, totalProductSum = 0;
for (int i = 0; i < nums.length() - 1; i++) {
// if the character is not digit, its not a valid id
if (!Character.isDigit(nums.charAt(i))) {
System.out.println("Invaild Id");
return;
}
// maintain the sum of products and increment the multiplier everytime
totalProductSum += (multiplier * (nums.charAt(i) - '0'));
multiplier++;
}
// the condition for validity i.e totalProduct sum mod 10 and last digit in input Id
if ((totalProductSum % 10) == (nums.charAt(nums.length() - 1) - '0'))
System.out.println("Valid Id");
else
System.out.println("Invaild Id");
}
Here, you can use this one also:
final class H4_Ruby {
public static void main(final String... args) {
System.out.printf("%s student ID%n", (H4_Ruby.isValid(H4_Ruby.read())) ? "Valid" : "Invalid");
}
private static String read() {
final Scanner scan = new Scanner(System.in);
// [start] do-while here for input validation: length and all characters must be digits
System.out.print("Please, enter a student ID between 6-10 digits: ");
final String input = scan.nextLine();
// [end] do-while here for input validation: length and all characters must be digits
return input;
}
private static boolean isValid(final CharSequence studentId) {
int partial = 0;
for (int i = 0; i < (studentId.length() - 1); i++) {
partial += ((i + 1) * Character.getNumericValue(studentId.charAt(i)));
}
return (partial % 10) == Character.getNumericValue(studentId.charAt(studentId.length() - 1));
}
}

Password Checking, Verification and Requirements

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();

Java excercise - checking ID number

I have a task with checking ID number and I must check if this ID has 11 characters, if those characters are digits and I must check control number. Number is correct when this equation is correct:
ID = abcdefghijk
(1*a+3*b+7*c+9*d+1*e+3*f+7*g+9*h+1*i+3*j+1*k) % 10 = 0
Sample correct ID is: 49040501580
And here is my program. I don't know how to check if ID is digit and why it isn't correct. Anyone help? XD
Thank you in advance :3
import java.util.*;
public class wat {
public static void main(String[] args) {
char[] weights = {1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1};
System.out.print("Enter next digits your ID number: ");
Scanner keyboard = new Scanner(System.in);
String number = keyboard.nextLine();
char[] ofm = number.toCharArray();
Character[] id = new Character[ofm.length];
for (int i = 0; i < ofm.length; i++) {
id[i] = ofm[i];
System.out.print(id[i] + " ");
int length = id.length;
if (length == 11) {
System.out.println("This ID number has 11 digits");
System.out.println("Checking of the control number");
int amount = 0;
amount = id[i] * weights[i];
System.out.println(amount);
int result = 0;
result = amount % 10;
if (result == 0) {
System.out.println("ID number is correct");
} else {
System.out.println("ID number is not correct");
break;
}
} else {
System.out.print("This ID number hasn't 11 digits.");
break;
}
}
}
}
Sample output
With a minimal number of changes to your original code, I believe this is what you need.
import java.util.*;
public class wat {
public static void main(String[] args) {
char[] weights = {1,3,7,9,1,3,7,9,1,3,1};
System.out.print("Enter next digits your ID number: ");
Scanner keyboard = new Scanner(System.in);
String number = keyboard.nextLine();
char[] ofm=number.toCharArray();
Character[] id=new Character[ofm.length];
if (ofm.length == 11) {
System.out.println("This ID number has 11 characters");
int amount = 0;
for (int i = 0; i < ofm.length; i++) {
id[i]=ofm[i];
System.out.print(id[i]+" ");
int length = id.length;
if (isDigit(id[i])) {
amount = id[i]*weights[i];
} else {
System.out.println("character is not a digit");
break;
}
}
} else {
System.out.print("This ID number hasn't 11 digits.");
return;
}
System.out.println("Checking of the control number");
System.out.println(amount);
int result =0;
result = amount % 10;
if (result == 0) {
System.out.println("ID number is correct");
} else {
System.out.println("ID number is not correct");
}
}
}
As you can see, we're now verifying the string length before the loop starts.
Then we're checking each character is a digit one by one and quitting with a new error message if one of them is not. You'll need to provide the isDigit function yourself (plenty to choose from on StackOverflow!).
We're accumulating the digit values multiplied by the weight into the amount variable, with a new value being added each time the loop iterates.
Finally we verify the result is correct after the loop has finished and all 11 characters have been processed.
NOTE: I don't normally work in Java so I'm not entirely sure if you can get the digit value out of a Character type object (to multiply it with the weight) like this. You might find that you are getting ASCII code values, or something else entirely. If this happens, you'll need to convert 'weights' into an array of integers, and extract the actual numeric value from the Character before multiplying them together.

binary to base10 in java with main method and TWO classes/method (boolean and

I am a beginner programmer. This is what I have so far. The directions for the question are kind of difficult. Here is what I am trying to accomplish..
You will write a program that converts binary numbers to base 10 numbers. This program will ask the user to enter a binary number. You will have to verify that what is entered by the user only has 0s and 1s. In the case the user entered letters, you have to keep asking the user for another input. When the input is valid, you will convert the binary number to a base 10 number. Please use the Question1.java file provided in the A2.zip file.
Valid input - In order to check if the input is valid your program should call the CheckInputCorrect method, which takes a String as an input parameter and returns a boolean value. An input string is considered valid if it corresponds to a number in binary representation.
More specifically, in the CheckInputCorrect method, you should scan this string to make sure it only contains ‘0’ or ‘1’ characters. As soon as you find a character that is not ‘0’ or ‘1’, the method should returns false. If the method reaches the end of the input string (i.e. all characters are ‘0’ or ‘1’) the method should return true.
Converter - At this point we assume that the input string is valid (checked with the CheckInputCorrect method). To convert the input from binary to base 10, you must implement the BinaryToNumber method. The BinaryToNumber method should take as parameter a String and return an integer, which corresponds to converted value in base 10.
The binary conversion should work as follows. For each digit in the binary number, if the digit is ‘1’ you should add the corresponding decimal value ( 20 for the rightmost digit, 21 for the next digits to the left, 22 for the next one, and so on) to a variable that will hold the final result to be returned. This can be easily accomplished by using a loop.
1) Am I on the right path?
2) I don't exactly know what I am doing and need you to help me figure that out....
Update1:
When I run this vvvv: It says "Please enter a binary number for me to convert: and then a place for me to type in my answer but whatever i put it just returns another box for me to type in but stops and doesn't evaluated anything.
import java.util.Scanner;
public class Question1
{
public static void main(String[] args)
{
System.out.println("Please enter a binary number for me to convert to decimal: ");
Scanner inputKeyboard = new Scanner(System.in);
String inputUser = inputKeyboard.nextLine();
boolean BinaryNumber = false;
String inputString = "";
while (!BinaryNumber){
inputString = inputKeyboard.next();
BinaryNumber = CheckInputCorrect(inputString);
System.out.println("You have given me a " + BinaryNumber + "string of binary numbers.");
}
int finalNumber = BinaryToNumber(inputString);
System.out.println("Congratulations, your binary number is " + finalNumber + ".");
}
public static boolean CheckInputCorrect(String input)
{
for (int i = 0; i < input.length(); i++)
{
while (i < input.length());
if (input.charAt(i) != '0' && input.charAt(i) != '1')
{return false;}
i++;
}
return true;
}
public static int BinaryToNumber(String numberInput)
{
int total = 0;
for (int i = 0; i < numberInput.length(); i++){
if (numberInput.charAt(i)=='1')
{
total += (int)Math.pow(2,numberInput.length() - 1 - i);
}
}
return total;
}
}
Original:
import java.util.Scanner;
public class Question1
{
public static void main(String[] args)
{
int binarynumber;
int arraySize = {0,1};
int[] binaryinput = new int[arraySize];
Scanner input = new Scanner(System.in);
System.out.println("Please enter a binary number");
binarynumber = in.nextInt();
if (binarynumber <0)
{
System.out.println("Error: Not a positive integer");
}
if (CheckInputCorrect) = true;
{
System.out.print(CheckInputCorrect);
}
public static boolean CheckInputCorrect(String input);
{
boolean b = true;
int x, y;
x = 0
y = 1
b = x || y
while (b >= 0 {
System.out.print("Please enter a binary number")
for (int i = 0; i < binarynumber.length; i++)
{
binaryinput[i] = in.nextInt();
if (binaryinput[i] = b.nextInt();
System.out.printl("Binary number is:" + binaryinput);
break outer;
if (binarynumber != b)
{
System.out.println("Error: Not a binary number")
}
return true;
}
}
public static int BinaryToNumber(String numberInput)
{
int remainder;
if (binarynumber <= 1) {
System.out.print(number);
return; // KICK OUT OF THE RECURSION
}
remainder = number %2;
printBinaryform(number >> 1);
System.out.print(remainder);
return 0;
}
}
}
As mentioned in my comments, your updated code contains two errors
while (i < input.length()); is an infinite loop, because it has no body. Therefore i cannot be increased and will stay lower than input.length().
inputString = inputKeyboard.next(); request another input after the first one and the first input will be ignored.
This is a fixed and commented version of your updated code:
public class Question1 {
public static void main(String[] args) {
System.out.println("Please enter a binary number for me to convert to decimal: ");
Scanner inputKeyboard = new Scanner(System.in);
String inputUser = inputKeyboard.nextLine();
//boolean BinaryNumber = false; // not needed anymore
//String inputString = ""; // not needed too
while (!checkInputCorrect(inputUser)) { // there is no reason for using a boolean var here .. directly use the returned value of this method
System.out.println("You have given me an invalid input. Please enter a binary number: "); // changed this message a little bit
inputUser = inputKeyboard.nextLine(); // re-use the "old" variable inputUser here
}
int finalNumber = binaryToNumber(inputUser);
System.out.println("Congratulations, your decimal number is " + finalNumber + ".");
}
public static boolean checkInputCorrect(String input) { // method names should start with a lower case letter
for (int i = 0; i < input.length(); i++) {
//while (i < input.length()); // this loop is deadly. Please think about why
if (input.charAt(i) != '0' && input.charAt(i) != '1') {
return false;
}
//i++; // what is the purpose of this? The "for" loop will increment "i" for you
}
return true;
}
public static int binaryToNumber(String numberInput) { //method name ... lower case letter ;)
int total = 0;
for (int i = 0; i < numberInput.length(); i++) {
if (numberInput.charAt(i) == '1') {
total += (int) Math.pow(2, numberInput.length() - 1 - i);
}
}
return total;
}
}

Categories

Resources