My teacher asked that we use the ASCII characters from 33 to 127 to generate a password that is n length. I got lost and am not sure where to go from here. This is what I have so far:
import java.util.*;
public class PasswordGenerator {
public static void main(String[]args){
Random random = new Random();
Scanner input = new Scanner(System.in);
System.out.print("Enter password length: ");
int length = input.nextInt();
StringBuilder password = new StringBuilder(length);
int count = random.nextInt(127-33+1)-33'
if(length<0) {
System.out.println(Invalid password length: "+length);
}
else {
for(int i = 33; i<126+1; i++) {
You are not using the Random object correctly, since as it is, you can generate negative numbers.
This is one way to implement what you are describing:
if(length<0) /*handle error*/;
StringBuilder password = new StringBuilder();
for(int i = 0; i < length ; i++) {
password.append((char) (random.nextInt(127-33+1)+33));
}
Here's the updated version:
public static void main(String[] args) {
Random random = new Random();
try(Scanner input = new Scanner(System.in);){
System.out.print("Enter password length: ");
int length = input.nextInt();
StringBuilder password = new StringBuilder();
if (length < 0) {
System.out.println("Invalid password length: " + length);
}
for(int i = 0 ; i < length ; i++){
password.append((char) (random.nextInt(127-33) + 33));
}
System.out.println(password.toString());
}
}
changes:
Count variable was not needed.
Length was not being utilized.
Scanner object was not closed, causing a resource leak.
Related
I am creating a program that generates a random password and asks the user to guess the generated password.
The problem I'm facing now is how to compare the generated password to the inputted password
My program compares the length of both passwords, but I don't know any possible way to compare both passwords to see if they're the same or not
The program has to compare both passwords and after three attempts, the program has to output the generated password
The code below is my program
final static Scanner in = new Scanner(System.in);
public static String method(int len){
String ASCII = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z";
int count =0;
int rand;
System.out.println("Guess the generated password");
String key = in.nextLine();
for(int i=0;i<key.length();i++){
count++;
}
SecureRandom sr = new SecureRandom();
StringBuilder sb = new StringBuilder();
for(int i =0;i<len;i++){
rand= sr.nextInt(ASCII.length());
sb.append(ASCII.charAt(rand));
}
for(int i=0;i<3;i++){
if(len!=count){
System.out.println("The length of the random generated password is "+ len+ " and the length of the password inserted is " + count);
System.out.println("The length of the generated password and the length of the inserted password varies. Please try again...");
System.out.println("Guess the generated password again");
key = in.nextLine();
}
}
return sb.toString();
}
public static void main(String[] args) {
Random r = new Random();
int len;
len = r.nextInt(1, 8);
System.out.println("length :" + len);
System.out.println(method( len));
}
}
You have made some strides in your coding since this post was originally placed. Based on your newest code shown below (from the post you deleted):
final static Scanner in = new Scanner(System.in);
public static String method(int len) {
//Create a variable to hold the ASCII character
String ASCII = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z";
int count = 0;
int rand;
System.out.println("Guess the generated password");
String key = in .nextLine();
for (int i = 0; i < key.length(); i++) {
count++;
}
SecureRandom sr = new SecureRandom();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
rand = sr.nextInt(ASCII.length());
sb.append(ASCII.charAt(rand));
}
for (int i = 1; i < 3; i++) {
while (len != key.length()) {
System.out.println("Length do not correspond please try again");
key = in .nextLine();
}
if (len == key.length() && !sb.toString().equals(key)) {
System.out.println("Length correspond but passwords differ, Try again");
key = in .nextLine();
}
}
System.out.print("The correct password is: ");
return sb.toString();
}
public static void main(String args[]) {
// Create a random length generator
Random r = new Random();
int len;
len = r.nextInt(1, 7);
System.out.println("lungezza :" + len);
System.out.println(method(len));
}
When generating a random number within a specific range like 1 inclusive to 7 inclusive then do it this way:
// int len = rand.nextInt((max - min) + 1) + min; thus...
int len = new Random().nextInt((7 - 1) + 1) + 1;
Don't add a bunch of whitespaces in your ASCII String variable. Consider not having whitespaces at all or if you have to, just provide one between the Upper and lower letters, for example:
String ASCII = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";
I say this because potentially, there is a good chance your random password generation could create a password that is all whitespaces which really isn't a password at all.
Also, I know your compiler isn't complaining but readers of your code will....consider using proper naming conventions for your variables, etc. ASCII should be ascii or even aSCII unless it is going to be a class Field variable which it is not. It is currently considered a method local variable. You actually did this correctly in this older post.
You can not guess an auto-generated password if that auto-generated password has not been generated yet. The code which auto-generates the password to guess is currently after the first prompt which asks you to supply what it is.
Move the code that generates the password above the code that asks the first prompt of what that password might be, for example:
//Create a variable to hold the ASCII characters
String ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";
// Generate the secret password to guess...
SecureRandom sr = new SecureRandom();
StringBuilder sb = new StringBuilder("");
int rand;
for (int i = 0; i < len; i++) {
rand = sr.nextInt(ascii.length());
sb.append(ascii.charAt(rand));
}
// Guess the password...
int count = 0;
System.out.print("Guess the generated password: -> ");
String key = in .nextLine();
for (int i = 0; i < key.length(); i++) {
count++;
}
This for loop under the first Guess prompt:
int count = 0;
System.out.print("Guess the generated password: -> ");
String key = in.nextLine();
for (int i = 0; i < key.length(); i++) {
count++;
}
is not required. All it does is count the number of characters contained within the first password guess. Ironically, you already know this by just using the key.length() method. You don't use the count variable for anything anyways so you may as well just get rid of all that:
// Guess the password (3 guesses)...
System.out.print("Guess the generated password: -> ");
String key = in .nextLine();
for (int i = 1; i < 3; i++) {
while (len != key.length()) {
System.out.println("Lengths do not correspond please try again");
key = in .nextLine();
}
if (len == key.length() && !sb.toString().equals(key)) {
System.out.println("Lengths correspond but passwords differ, Try again");
key = in .nextLine();
}
}
System.out.print("The correct password is: ");
return sb.toString();
In reality, you only need one prompt and it's always nice to validate the User's input. Here is an alternative way to do this:
private final static Scanner in = new Scanner(System.in);
private static int numberOfGuessesAllowed = 3;
private static boolean correct = false;
public static void main(String args[]) {
// Create a random length generator
Random r = new Random();
int len = r.nextInt((7 - 1) + 1) + 1;
System.out.println("Password to guess contains " + len + " characters.");
System.out.println("You have " + numberOfGuessesAllowed + " attempts to guess it right!");
System.out.println(method(len));
}
public static String method(int len) {
//Create a variable to hold the ASCII characters
String ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz";
// Generate the secret password to guess...
SecureRandom sr = new SecureRandom();
StringBuilder sb = new StringBuilder("");
int rand;
for (int i = 0; i < len; i++) {
rand = sr.nextInt(ascii.length());
sb.append(ascii.charAt(rand));
}
String secretPassword = sb.toString();
// Guess the password...
String key = "";
while (key.isEmpty() && numberOfGuessesAllowed > 0) {
System.out.print("Guess the generated password (q to quit): -> ");
key = in .nextLine().trim();
if (key.equalsIgnoreCase("q")) {
return "Quitting! Bye-Bye.";
}
if (key.isEmpty()) {
System.out.println("Invalid Entry! Try again...\n");
}
else if (secretPassword.equals(key)) {
correct = true;
break;
}
else if (len != key.length()) {
numberOfGuessesAllowed--;
System.out.println("Lengths do not correspond! Please try again.\n");
key = "";
}
else if (len == key.length() && !secretPassword.equals(key)) {
numberOfGuessesAllowed--;
System.out.println("Lengths correspond but passwords differ, Try again\n");
key = "";
}
}
if (correct) {
System.out.print("You guessed it! The password is: ");
}
else {
System.out.print("You couldn't do it! The correct password is: ");
}
return secretPassword;
}
So what I am trying to do is create a random password generator, I have managed to make the system produce a random string of characters based on the char length that the user inputs. What I then want to do is ask the user if they want to save the file. On the file I want to include the name of the website/application and the password.
My problem is I cannot get the random string for the password to be stored as a variable, does anyone know how to fix this?
Code can be seen below:
System.out.println("Please enter the length of password that you require: ");
int passwordLength = sc.nextInt();
sc.nextLine();
Random r = new Random();
String alphabet = "abcde5678fghijklmn123opqrs?!£$%tuvwxyzABCDEFGHIJKLMN490##/*(OPQRSTUVWXYZ)";
for (int i = 0; i < passwordLength; i++) {
System.out.print(alphabet.charAt(r.nextInt(alphabet.length())));
}
I believe you mean that you want to collect the password into a String variable instead of printing each character. Here's how to do that in a completely working example:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the length of password that you require: ");
int passwordLength = sc.nextInt();
sc.nextLine();
Random r = new Random();
String alphabet = "abcde5678fghijklmn123opqrs?!£$%tuvwxyzABCDEFGHIJKLMN490##/*(OPQRSTUVWXYZ)";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < passwordLength; i++)
sb.append(alphabet.charAt(r.nextInt(alphabet.length())));
String password = sb.toString();
System.out.print(password);
}
Result:
Please enter the length of password that you require:
12
j$miDCadnJMd
If you dont want to use a String Builder, you could do this
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the length of password that you require: ");
int passwordLength = sc.nextInt();
sc.nextLine();
Random r = new Random();
String alphabet = "abcde5678fghijklmn123opqrs?!£$%tuvwxyzABCDEFGHIJKLMN490##/*(OPQRSTUVWXYZ)";
String password = "";
for (int i = 0; i < passwordLength; i++)
password += (alphabet.charAt(r.nextInt(alphabet.length()))) + "";
System.out.print(password);
}
I'm a beginner in Java and working on a code that first requires user to enter total number of integers and next the integers themselves. Example input is:
4
1 4 3 2
The code will need to reverse the second input to the following:
2 3 4 1
My solution is as follow:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for(int arr_i=0; arr_i < n; arr_i++){
arr[arr_i] = in.nextInt();
}
for(int reverse_i=n-1; reverse_i>=0; reverse_i--){
System.out.print(arr[reverse_i]);
if(reverse_i != 0){System.out.print(" ");}
}
}
My question is related to the code to add a blank space " " in between the printed numbers. I wonder what other way I can use to get this done? Any suggestion is appreciated, thank you.
The easy way to reverse a string is using the StringBuilder class:
One option is to remove the spaces at the end of the string eg. remove last char
package stackoverflow.main;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
StringBuilder sb = new StringBuilder();
for(int arr_i = 0; arr_i < n; arr_i++){
sb.append(in.nextInt());
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
String normal = sb.toString();
String reversed = sb.reverse().toString();
System.out.println("normal: " + normal);
System.out.println("reversed: " + reversed);
}
}
Another option is to check whether you are at the last arr_i of your loop.
If so, then don't add a space
package stackoverflow.main;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
StringBuilder sb = new StringBuilder();
for(int arr_i = 0; arr_i < n; arr_i++){
sb.append(in.nextInt());
if (arr_i != 3
sb.append(" ");
}
String normal = sb.toString();
String reversed = sb.reverse().toString();
System.out.println("normal: " + normal);
System.out.println("reversed: " + reversed);
}
}
First reverse the array and then print it with a for loop.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for(int arr_i=0; arr_i < n; arr_i++)
{
arr[arr_i] = in.nextInt();
}
for(int i = 0; i < arr.length / 2; i++)
{
int temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
for(int i = 0; i < arr.length; i++)
{
System.out.print(arr[i]+" ");
}
}
}
It is all about output formatting. You may use this examples and become familiar with all possible approaches.
Your code can be improved in next two ways :
1) Use \t instead of Empty Space (\t is a tabulation)
2) Create a constant with output format like this private static final String output = "%d " and use it in output line like this : String.format(output, number) where number is your number that should be printed.
Im trying to collect some data from a user and display it with the user input. the example i was giving is:
Filename: output.txt
number of lines: 4
Line Length: 8
Character Set: ABC123
2CB3A32C
BB13CAA3
C3A21CB2
CC2B13A3
i currently have gotten the user input but i dont know how to display the random letters and numbers based on the input. Here is my code. Any help would be big.
the data has to be displayed using Loop.
public static void main(String[] args) throws IOException
{
int lineNum = 0;
int numChars = 0;
String charSet = "";
String userInput = "";
String filename;
//Creates a Scanner Object for keyboard input.
Scanner keyboard = new Scanner(System.in);
//Get the filename.
System.out.print("Enter a filename: ");
filename = keyboard.nextLine();
System.out.print("Enter number of lines: ");
lineNum = keyboard.nextInt();
if( lineNum < 1 || lineNum > 20){
lineNum = 20;
System.out.println("Defaulting to 20 lines");
}
System.out.print("Enter number of characters in each line: ");
numChars = keyboard.nextInt();
keyboard.nextLine();
if( numChars < 1 || numChars > 20){
numChars = 20;
System.out.println("Defaulting to 20 characters");
}
System.out.print("Enter character set: ");
charSet = keyboard.nextLine();
//Put all the input together to display the results
PrintWriter pw = new PrintWriter(filename);
pw.println("\nFilename: " + filename);
pw.println("Number of lines: " + lineNum );
pw.println("Line Length: " + numChars );
pw.println("Character set: " + charSet );
pw.println("\n" + userInput );
pw.close();
// Read the file
BufferedReader br = new BufferedReader(new FileReader(filename));
for (String line; (line = br.readLine()) != null;) {
System.out.println(line);
}
}
Try this.
Random random = new Random();
for (int i = 0; i < lineNum; ++i) {
for (int j = 0; j < numChars; ++j)
pw.print(charSet.charAt(random.nextInt(charSet.length())));
pw.println();
}
Take a look at: RandomStringUtils
This might help get you on the right track:
import org.apache.commons.lang.RandomStringUtils;
System.out.println(RandomStringUtils.random(8,new char[]{'a','b','c','1', '2', '3'}));
Try:
str.charAt(ThreadLocalRandom.current().nextInt(0, str.length()));
In Java8
final int length = 8;
final Random rand = new Random();
String random = IntStream.range(0, length).mapToObj(i -> str.charAt(rand.nextInt(100) % str.length()) + "").collect(Collectors.joining());
System.out.println(random);
random string generated for 10 runs
A31CCCB3
1AC3A2CA
BAB11B2A
A33A1ACA
BCCCB2AC
331C12CA
3CC1AAB3
113BAABB
1BC22B1A
31BBCAC1
You can use the below Utilty class
import java.util.Random;
public class RandomString {
private char[] symbols;
private final Random random = new Random();
private final char[] buf;
public RandomString(int length ,char[] symbols) {
if (length < 1)
throw new IllegalArgumentException("length < 1: " + length);
buf = new char[length];
this.symbols = symbols;
}
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
To Use it from your main,
RandomString randString = new RandomString(numChars ,charSet.toCharArray());
for (int i = 0; i < lineNum; i++) {
System.out.println("" +randString.nextString());
}
import java.util.Scanner;
class Digitsdisplay {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
System.out.println("Please enter a value: ");
int value = input.nextInt();
int total = 0;
String digit = "" + value;
System.out.print("");
for (int i = 0; i < digit.length(); i++) {
int myInt = Integer.parseInt(digit.substring(i, i + 1));
System.out.println(myInt);
total += myInt;
}
}
}
output:
Please enter a value:
789
7
8
9
How do I reverse the output? For example, when I enter the number 123, it would display 321 with each digit on a new line.
If the user is inputting values in base 10, you could instead use the modulo operator along with integer division to grab the rightmost values successively in a while loop as so:
import java.util.Scanner;
public class Digitsdisplay {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
System.out.println("Please enter a value: ");
int value = input.nextInt();
int quotient = value;
int remainder = 0;
while(quotient != 0){
remainder = quotient%10;
quotient = quotient/10;
System.out.print(remainder);
}
}
}
This might be a better method that attempting to convert the int to a string and then looping through the string character by character.
Loop you printing for loop in the reverse direction:
import java.util.Scanner;
class Digitsdisplay {
public static void main(String args[]){
Scanner input = new Scanner(System.in);
System.out.println("Please enter a value: ");
int value = input.nextInt();
int total = 0;
String digit = "" + value;
System.out.print("");
for (int i = digit.length()-1; i >= 0; i--) {
int myInt = Integer.parseInt(digit.substring(i, i + 1));
System.out.println(myInt);
total += myInt;
}
}
}
Edit: No reason to reverse the string itself, ie. using a Stringbuilder like the other answers say. This just adds to the runtime.
import java.util.*;
public class Francis {
public static void main(String[] args) {
Scanner input= new Scanner (System.in);
System.out.println("Please enter a value: ");
int value = input.nextInt();
int total = 0;
String digit = "" + value;
System.out.print("");
for (int i = 0; i < digit.length(); i++) {
int myInt = Integer.parseInt(digit.substring(i, i + 1));
System.out.println(myInt);
total += myInt;
}
}
}
Simply reverse the string before looping through it
digit = new StringBuilder(digit).reverse().toString();