简体   繁体   中英

Trouble with recursive method java

basically I have a brute force password guesser(I realize it's not very efficient) I have a process I want to make into a recursive method that i can pass a length integer and it will run with that amount of characters. here is the code:

public static void generatePassword(int length)
{
    // should be a recusive function learn how to do that
    // 1 interval
    for(int i =32;i<127;i++)// ascii table length
    {
                System.out.println((char)i);

    }
    // 2 interval
    for(int z =32;z<127;z++)// ascii table length
    {
        for(int q =32;q<127;q++)// ascii table length
        {
            System.out.println((char)z+""+(char)q);

        }

    }
    // 3 interval
    for(int w =32;w<127;w++)// ascii table length
    {
        for(int o =32;o<127;o++)// ascii table length
        {
            for(int g =32;g<127;g++)// ascii table length
            {
            System.out.println((char)w+""+(char)o+""+(char)g);
            }
        }


    }

}

the intervals return a string with that length example: 3rd interval will return every possible string combination with a length of 3. if anyone can help me automate this process and explain(i would like to learn rather then copy and paste) that would be great ! :)

A recursive method is a method that calls itself, it has a base-condition (also called stop condition) which prevents it from going into an infinite loop.

Lets take the first interval as an example:

for(int i = 32; i < 127; i++) { // ascii table length
    System.out.println((char)i);
}

we can create a recursive method that'll do the same thing:

private void interval1(int i) {
    if (i < 32 || i >= 127) return;
    System.out.println((char)i);
    interval1(i + 1);
}

in order to use it for our use-case, we should call this method with i=32: interval(32)

Hope this helps!

Here is your method implemented using recursion:

public static void generatePassword(int length, String s) {
        if (length == 0) {
            System.out.println(s);
            return;
        }
        for (int i = 32; i < 127; i++) {
            String tmp  = s+((char) i);
            generatePassword(length - 1, tmp);
        }
    }

All you have to do is to pass length and initial String (ie "") to it.
At if statement there is checked, if recursion should be stopped (when length of generated password is equals to expected).
At for-loop there is new character added to actual String and the method is invoked with shorter length and a new String as an argument.

Hope it helps.

The function

Note that this will be EXTREMELY INEFFICIENT. This shouldn't ever be done in practice, since the number of String objects created is MIND-BOGGLINGLY HUGE (see bottom of answer)

public void recursivePrint(String prefix, int levels) {
    if (levels <= 1) {
        for (int i = 33; i < 127; ++i) {
            System.out.println(prefix+(char)i);
        }
    } else {
        for (int i = 33; i < 127; ++i) {
            recursivePrint(prefix+(char)i, levels-1);
        }
    }
}

Then you call it with:

recursivePrint("", 5); // for printing all possible combinations of strings of length 5

The way it works

Each call to a function has it's own memory, and is stored seperately. When you first call the function, there is a String called prefix with a value of "", and an int called 'levels' which has a value of 5. Then, that function calls recursivePrint() with new values, so new memory is allocated, and the first call will wait until this new call has finished.

This new call has a String called prefix with a value of (char)34+"" , and a levels with a value of 4. Note that these are completely separate instances of these variables to the first function call because remember: each function call has it's own memory (the first call is waiting for this one to finish). Now this second call makes another call to the recursivePrint() function, making more memory, and waiting until this new call finishes.

When we get to levels == 1, there is a prefix built up from previous calls, and all that remains is to use that prefix and print all the different combinations of that prefix with the last character changing.

Recursive methods are highly inefficient in general, and in this case especially.

Why you should never use it

This method is not just inefficient, though; it's infeasible for anything useful. Let's do a calculation: how many different possibilities are there for a string with 5 characters? Well there's 127-33=94 different characters you want to choose, then that means that you have 94 choices for each character. Then the total number of possibilities is 94^5 = 7.34*10^9 [that's not including the 5+ bytes to store each one] (to put that in perspective 4GB of RAM is around 4*10^9 bytes)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM