Java pword-generator does not update random inside loop - java

Im working on an assignment for school where i am going to finish a short password generator.
when trying to loop adding characters out of the string, it ends up adding the same character, but if i would just print out characters it gives different ones. could someone explain why this is? i would really like to learn.
private void program() {
System.out.println(generate(all));
}
Random rand = new Random();
String all = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int randomInt = rand.nextInt(all.length());
char randomchar = all.charAt(randomInt);
StringBuilder sb = new StringBuilder();
String generate (String string) {
while (sb.length() < 10) {
sb.append(randomchar);
}
return sb.toString();
}
}

You are setting nextInt and nextChar gloabally. This need to be moved to your generation method.
String generate (String string) {
StringBuilder sb = new StringBuilder();
while (sb.length() < 10) {
int randomInt = rand.nextInt(all.length());
char randomchar = all.charAt(randomInt);
sb.append(randomchar);
}
return sb.toString();
}

Size your StringBuilder for efficiency (and big passwords)
public String generatePassword(String candidateChars, int passwordLength) {
Random rand = new Random();
int max = candidateChars.length();
StringBuilder sb = new StringBuilder(passwordLength);
for (int i = 0; i < passwordLength; i++) {
char randomchar = candidateChars.charAt(rand.nextInt(max));
sb.append(randomchar);
}
return sb.toString();
}

You should (re-)generate randomInt as well as randomchar within loop:
while (sb.length() < 10) {
// we want fresh value on ach itteration
int randomInt = rand.nextInt(all.length());
char randomchar = all.charAt(randomInt);
sb.append(randomchar);
}

Related

saving random letters of an array as a String

I wanna write a program in which different letters of a String Array form different words based on random orders. The most important part is that letters should not be duplicate in one word. I could somehow make the correct pattern but the problem is that I can only show them on console and couldn't find a way to save them as a String (like "OMAN"). Here is my code :
int size = 4;
ArrayList<Integer> list = new ArrayList<Integer>(size);
Random rnd = new Random();
while (list.size()<size) {
int random = rnd.nextInt(size);
if (!list.contains(random)) {
list.add(random);
}
}
String[] words = {"M","O","A","N"};
for(int i=0 ; i<size ; i++){
System.out.println(words[list.get(i)]);
}
You could accumulate them to a StringBuilder:
StringBuilder sb = new StringBuilder(size);
for(int i = 0 ; i < size ; i++) {
sb.append(words[list.get(i)]);
}
String result = sb.toString();
First declare a blank string
String answer = "";
Then in your for loop do
answer+=words[list.get(i)];
When you leave the for loop
System.out.println(answer);
Will have what you want. To do it more efficiently I'd read up on StringBuilder.
You can do something like this,
int size = 4;
ArrayList<Integer> list = new ArrayList<Integer>(size);
Random rnd = new Random();
while (list.size() < size) {
int random = rnd.nextInt(size);
if (!list.contains(random)) {
list.add(random);
}
}
String[] words = {"M", "O", "A", "N"};
String finalWord = "";
for (int i = 0; i < size; i++) {
finalWord += words[list.get(i)];
}
System.out.println(finalWord);

Generate Random String in java [duplicate]

This question already has answers here:
How to generate a random alpha-numeric string
(46 answers)
Closed 6 years ago.
I'm trying to generate a string between capital A-Z in java using Secure Random. Currently I'm able to generate an alphanumeric string with special characters but I want a string with only upper case alphabets.
public String createRandomCode(int codeLength, String id){
char[] chars = id.toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < codeLength; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
System.out.println(output);
return output ;
}
The input parameters are length of the output string & id whhich is alphanumeric string.Can't understand what modifications to make to the above code to generate only upper case alphabet string. Please help..
Your method randomly selects characters out of the id argument. If you want those to only be uppercase letters, then pass a string with those characters:
String randomCode = createRandomCode(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
EDIT If you want to avoid duplicates, you can't just select characters at random. You'll want to shuffle them and pick out the first n characters:
public String createRandomCode(int codeLength, String id) {
List<Character> temp = id.chars()
.mapToObj(i -> (char)i)
.collect(Collectors.toList());
Collections.shuffle(temp, new SecureRandom());
return temp.stream()
.map(Object::toString)
.limit(codeLength)
.collect(Collectors.joining());
}
EDIT 2 Just for fun, here's another way to implement the original random code generator (allowing duplicates):
public static String createRandomCode(int codeLength, String id) {
return new SecureRandom()
.ints(codeLength, 0, id.length())
.mapToObj(id::charAt)
.map(Object::toString)
.collect(Collectors.joining());
}
Here is generator that I wrote and use:
public class RandomGenerator {
private static final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String generateRandom(int length) {
Random random = new SecureRandom();
if (length <= 0) {
throw new IllegalArgumentException("String length must be a positive integer");
}
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(characters.charAt(random.nextInt(characters.length())));
}
return sb.toString();
}
}
in numChars string you can put any characters you want to be included. int length parameter is the length of generated random string.
Here is an example method that uses the int range for characters A to Z (also this method avoids duplicate characters in the String) :
public String createRandomCode(final int codeLength) {
int min = 65;// A
int max = 90;// Z
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < codeLength; i++) {
Character c;
do {
c = (char) (random.nextInt((max - min) + 1) + min);
} while (sb.indexOf(c.toString()) > -1);
sb.append(c);
}
String output = sb.toString();
System.out.println(output);
return output;
}
The range part comes from this topic : Generating random integers in a specific range

Cannot find symbol error Java

So I was creating this random string generator:
public class Test {
public static void main(String[] args) {
String strings = "abcdefghijklmnopqrstuvwxyz1234567890!##$%&()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random generator = new Random(System.currentTimeMillis());
int stringLength = strings.length()-1;
Character character;
for (int i = 0; i < stringLength; i++) {
Double test = new Double(Math.random());
character = strings.charAt(test.intValue());
String outputString = outputString.concat(character.toString());
}
System.out.println(outputString);
}
}
I went an compiled it using javac Test.java, and it gave me the error outputString might not have been initialised for lines 14 and 16. So I added the String keyword to line 14, and now it's telling me
cannot find symbol: variable outputString
Why is this so?
EDIT:
Okay so I took up the suggestions, and this is the code currently:
public class Test {
public static int randomInt(int min, int max, long seed) {
Random rand = new Random(seed);
int randomNum = rand.nextInt((max-min)+1) - min;
return randomNum;
}
public static void main(String[] args) {
String strings = "abcdefghijklmnopqrstuvwxyz1234567890!##$%&()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int stringLength = strings.length()-1;
Character character;
for (int i = 0; i < stringLength; i++) {
Double test = new Double(randomInt(0, stringLength, System.currentTimeMillis()));
character = strings.charAt(test.intValue());
System.out.print(character);
}
}
}
The code runs without errors, but it doesn't print anything.
I'm currently using Command Prompt to compile it.
You are defining the outputString only inside of the for loop. It will not be available outside.
You could output the characters directly:
for (int i = 0; i < stringLength; i++) {
Double test = new Double(Math.random());
character = strings.charAt(test.intValue());
System.out.print(character);
}
System.out.println();
If you insist on concatenating a String in a loop, please use StringBuilder instead.
The next problem you will run into:
Double test = new Double(Math.random());
strings.charAt(test.intValue());
That will always get the the first character. The double will be between 0 (inclusive) and 1 (exclusive).
You need to create a random integer between 0 and the length of your alphabet.
The compiler is correctly telling that outputString is not declared correctly. The outputString is declared within the for loop, but you are trying to print the value outside.
A quick way to fix this would be to declare outputString outside the for loop by having outputString = "";
outputString is only defined within the block of the for loop, so once you exit it, it no longer exists. To make sure that your code works, define it outside the loop:
String outputString = "";
for (int i = 0; i < stringLength; i++) {
Double test = new Double(Math.random());
character = strings.charAt(test.intValue());
outputString += character.toString();
}
System.out.println(outputString);
It is because you are calling outputString.concat before you have intialized it
try
String outputString = "";
outputString = outputString.concat(character.toString());`
I managed to get it to work using the following code:
import java.util.Random;
public class Test{
public static void print(String str) {
System.out.print(str);
}
public static int randomInt(int min, int max) {
Random rand = new Random(System.currentTimeMillis());
int randomNum = rand.nextInt((max-min)+1) - min;
return randomNum;
}
public static void main(String[] args) throws InterruptedException {
String strings = "abcdefghijklmnopqrstuvwxyz1234567890!##$%&()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int len = strings.length() - 1;
StringBuilder outputString = new StringBuilder(len);
for (int i = 0; i < len; i++) {
Double test = new Double(randomInt(0, len));
Integer value = test.intValue();
if (value <= len) {
//print(value.toString()); For testing purposes
outputString.append(strings.charAt(value));
Thread.sleep(1);
}
else {i--;}
}
print(outputString + "\n");
}
}

Change a certain occurrence of a letter in a string

Say I have a string, and I want to change the second "a" in that string to an "e".
String elephant = "elaphant";
I tried using String.replace(), but that replaces all the a's in the string, returning "elephent".
elephant.replace("a", "e");
Is there any loop or method I can use to accomplish this? Thank you all.
You could convert it to a char array, switch out the desired letter, then convert it back to String?
String elephant = "elaphant";
int index = -1;
int count = 0;
while(count < 2) {
index = elephant.indexOf("a", index+1);
count++;
}
if(index >= 0 && index < elephant.length()) {
char[] tmp = elephant.toCharArray();
tmp[index] = "e";
elephant = new String(tmp);
}
Or if you prefer StringBuilder
StringBuilder sbTemp = new StringBuilder(elephant);
sbTmp = sbTmp.replace(index, index+1, "e");
elephant = sbTmp.toString();
You need to get the index of the first occurrence of a letter.
Try using the indexOf method.
int myIndex = elephant.indexOf('a');
Once you have the index, use StringBuilder to replace the value. Something like:
StringBuilder sb = new StringBuilder(elephant);
sb[index] = myIndex;
elephant = sb.ToString();
Code:
String elephant = "elaphant";
//convert the string to array of string
String[] sp = elephant.split("");
int countA = 0;
boolean seenTwice = false;
String result = "";
for (int i = 0; i < sp.length; i++) {
//count number of times that a has been seen
if (sp[i].equals("a")) {
countA++;
}
// if a has been seen twice and flag seenTwice has not been see
if (countA == 2 && !seenTwice) {
result += "e";
seenTwice = true;
} else {
result += sp[i];
}
}
System.out.println(result);
Output:
elaphent

Converting String to it's integer ascii values

I'm stuck at the very end of my problem getting a NumberFormatException.
I want to take a string such as Wsup, and turn it into its ASCII values with the result, '87115117112'.
I've gotten that string of numbers built successfully a couple different ways, but when I try to parseInt(string) on it, I get my exception. I've tried printing out the string as an array of characters to look for hidden white space, I've used String.trim() with no luck, I'm quite confused why it isn't recognized as a valid integer.
public static int toAscii(String s){
StringBuilder sb = new StringBuilder();
String ascString = null;
long asciiInt;
for (int i = 0; i < s.length(); i++){
sb.append((int)s.charAt(i));
char c = s.charAt(i);
}
ascString = sb.toString();
asciiInt = Integer.parseInt(ascString); // Exception here
return 0;// asciiInt; 0 in place just to run
}
Thanks for any help given.
Yor asciiInt is long type so do it in this way
asciiInt = Long.parseLong(ascString);
here is your full function
public static long toAscii(String s){
StringBuilder sb = new StringBuilder();
String ascString = null;
long asciiInt;
for (int i = 0; i < s.length(); i++){
sb.append((int)s.charAt(i));
char c = s.charAt(i);
}
ascString = sb.toString();
asciiInt = Long.parseLong(ascString);
return asciiInt;
}
You need to return as long not as integer I have implement your toAscii() with little bit
public static long toAscii(String s){
StringBuilder sb = new StringBuilder();
long asciiInt;
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
asciiInt = (int)c;
System.out.println(c +"="+asciiInt);
sb.append(asciiInt);
}
return Long.parseLong(sb.toString());
}

Categories