I'm trying to write a code that will output all possible passwords from a given array recursively, e.g. given the input
"ab"
will output the next:
a
b
aa
ab
ba
bb
the problem is that I'm instructed to use only one loop in the crack()
function below and that's it. I cannot use any other functions, just those two.
This is what I've got so far:
import java.util.*;
public class PasswordGen {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a string:");
char array[] = sc.next().toCharArray();
System.out.println("All Combination:");
crack(array);
sc.close();
}
static void crack(char[] array) {
for (int i = 1; i <= array.length; i ) {
generate(array, i, "", array.length);
}
}
static void generate(char[] array, int i, String string, int length) {
//recursion stopping if condition is meet
if (i == 0) {
System.out.println(string);
return;
}
for (int j = 0; j < length; j ) {
String charArray = string array[j];
generate(array, i -1, charArray , length);
}
return;
}
}
Is there a way to get the same output without using the for
loop in the generate()
function?
(see code below).
static void generate(char[] array, int i, String string, int length) {
//recursion stopping if condition is meet
if (i == 0) {
System.out.println(string);
return;
}
for (int j = 0; j < length; j ) {
String charArray = string array[j];
generate(array, i -1, charArray , length);
}
Any suggestions/better way to do it?
CodePudding user response:
Not sure if this answers your question, but here is a class that does what you want without any for loop:
import java.util.*;
import java.util.stream.*;
class Bruteforcer {
private List<Integer> state = Collections.singletonList(0);
private final String allowedChars;
private final Integer maxLength;
public Bruteforcer(String allowedChars, Integer maxLength){
assert allowedChars != null;
assert allowedChars.length() > 0;
assert maxLength > 0;
this.allowedChars = allowedChars;
this.maxLength = maxLength;
}
public String next(){
final var allIndexesAreLastChar = this.state.stream().allMatch(i -> i == this.allowedChars.length() - 1);
final var currentLength = this.state.size();
if (currentLength > this.maxLength){
return null;
}
final var nextPassword = this.state.stream()
.map(i -> this.allowedChars.substring(i, i 1))
.collect(Collectors.joining(""));
if (allIndexesAreLastChar){
this.state = Collections.nCopies(currentLength 1, 0);
return nextPassword;
}
this.state = IntStream.range(0, currentLength)
.mapToObj(i -> {
final var current = this.state.get(currentLength - 1 - i);
final var mustIncrement = i == 0 || this.state.get(currentLength - i) == this.allowedChars.length() - 1;
if (mustIncrement){
return current == this.allowedChars.length() - 1 ? 0 : current 1;
}
return current;
})
.collect(Collectors.toList());
Collections.reverse(this.state);
return nextPassword;
}
}
class FindPasswordApplication {
public static void main(String[] args) {
final var bruteforcer = new Bruteforcer("ab", 2);
for (var i = 0; i < 10; i ){
final var password = bruteforcer.next();
System.out.println(password);
}
}
}