Any way to prevent this brute force method from throwing StackOverflowError?

65 Views Asked by At
// this is the recursive method used to crack the 3 digit password
// takes three integer arguments each representing the index of a letter in the above alphabet string
public static String brute(int a, int b, int c) {
    // boolean signifying whether or not the password was correct
    boolean isCorrect = false;

    // string variable representing the password as a concatenation of characters from the alphabet string
    String string = "" + alphabet.charAt(a) + alphabet.charAt(b) + alphabet.charAt(c);
    System.out.println(string);

    try {
        ZipFile zip = new ZipFile("protected3.zip");
        zip.setPassword(string);
        zip.extractAll("contents");
        System.out.println("Successfully cracked!");
        isCorrect = true;
    } catch (ZipException ze) {

    } catch (Exception e) {
        e.printStackTrace();
    }  
    
    // base case
    if (isCorrect) {
        return string;
    }
    // recursive steps
    else {
        if (alphabet.length() - 1 <= c) {
            return brute(a, b + 1, 0);
        }
        else if (alphabet.length() - 1 <= b) {
            return brute(a + 1, 0, c);
        }
        else {
            return brute(a, b, c + 1);
        }
    }
}

Here I have a method that is meant to brute force a 3 digit lowercase password on a zip file recursively. It works correctly, but once the password attempts get to around "fff" the program throws a StackOverflowError. I know that intense recursion is taxing on the stack, but is there any way around this problem with recursion or will I have to re-implement this as a not-so elegant loop? Thanks for any help.

1

There are 1 best solutions below

0
John Williams On

Recursion is fine but your algorithm is broken. It needs a depth-first search, ie a level of recursion per letter, ie 3.

The problem is that all the logical branches in brute() besides when the unzip works, simply call brute().

You need to add a condition for the end of the alphabet to return without calling brute().