0

I have this homework assignment to make a recursive method to crack a password of a given length, n (unlimited and unknown!) made of small English letters, a-z ONLY.

Here's the class "Password" that creates a random password:

import java.util.Random;

public class Password {
private String _password = "";

public Password(int length) {
    Random generator = new Random();
    for (int i = 0; i < length; ++i) {
        this._password = this._password + (char) (generator.nextInt(26) + 97);
    }
}

public boolean isPassword(String st) {
    return st.equals(this._password);
}

public String getPassword() {
    return this._password;
  }
}  

And here is the question in detail: "You must write a static recursive method, public static String findPassword(Password p, int length) that "cracks" the code. Here's an example of a main method:

public class Main {                                                                                                     
    public static void main(String[] args) {                                                                            
        Password p = new Password(5);                                                                                   
        System.out.println(p.getPassword());                                                                            
        System.out.println(Ex14.findPassword(p, 5));                                                                    
    }                                                                                                                   
}       

Important notes:

  1. The method MUST be recursive, without using ANY loops.
  2. You may not use the getPassword method.
  3. If you would like to use a method of the String class, you may only use the following: charAt, substring, equals, length.
  4. You MAY use overloading, but you MAY NOT use other methods. (You cannot use String.replace/String.replaceall)
  5. You MAY NOT use static(global) variables.
  6. You MAY NOT use any Array. "

Here's what I have until now, which clearly doesn't work; :\

public static String findPassword(Password p, int length) {
    return findPassword(p, length, "", 'a');
}

public static String findPassword(Password p, int length, String testPass, char charToChange) {
    int currDig = testPass.length() - 1;
    if (p.isPassword(testPass))
        return testPass;
    if (length == 0) // There is no password.
        return ""; // Returns null and not 0 because 0 is a password.
    if (length > testPass.length())
        return findPassword(p, length, testPass + charToChange, charToChange);
    if (testPass.length() == length) {
        //TODO if charToChange is 'z', then make it the one before it '++', and reset everything else to a.
        //if (charToChange == 'z') {
            // charToChange = 'a';
            // String newString = testPass.substring(0, currDig-1) +
            // (charToChange++)
            // +testPass.substring(currDig+1,testPass.length()-1);
            System.out.println("it's  z");
            // TODO currDig --;
            // String newerString = testPass.substring(0, currDig - 1)
            // + (char) (testPass.charAt(testPass.length() - 1) - 25);
            // currDig--;
        }
        return "";  
}

Thank you very much! much appreciated! - TripleS

zapl
  • 63,179
  • 10
  • 123
  • 154
TripleS
  • 51
  • 1
  • 6
  • 1
    I think I have a solution, however it's failing with a stackoverflow exception because the callstack gets too long. Passwords of length 3 require already over 18k steps and I crash at around 4k. (http://pastebin.com/uGE1LbnU is some debug from my algorithm, maybe you can figure out what I did there :) ) – zapl May 23 '16 at 20:14
  • @zapl :P Thanks for the answer! I know what I should do, but not how to implement it. And also, it shouldn't check for fb after fza, straight to fba. – TripleS May 23 '16 at 20:42
  • Shouldn't it check for "fzb" after "fza" ? What if the password in question is "fzu" (it needs to exhaust that first) – Michael Markidis May 23 '16 at 20:44
  • @TripleS You mentioned that you would know what to do, just not how to implement it. Could you provide that in your post. That would help show what algorithm you are thinking which can help a potential user answer it. – Michael Markidis May 23 '16 at 20:49
  • Yeah sorry, misscopied. – TripleS May 23 '16 at 21:00
  • 1
    Ah, I found my mistake & made it backtrack properly. The secret is: try to find password in children (`testPass + 'a'`) first, if there is none, it must be in the siblings. So, if there are more siblings (last character != z), return the result of searching through them (`incrementLastCharOf(testPass)`). – zapl May 23 '16 at 21:17
  • @MichaelMarkidis I did provide what I have. I've also written TODO because I got the idea. – TripleS May 25 '16 at 03:25
  • @zapl Thanks, if you could share a code it will be awesome :-) Thanks everyone! – TripleS May 25 '16 at 03:26
  • TripleS, I'm in your course, and your idea is identical to mine - go from 'a' to 'z' in the last character, and if 'z' was reached - increase the character before it and go again from 'a' to 'z'. However, as @zapl wrote, it causes stack overflow for passwords with 4 and more characters unless you're manually increasing the stack size (adding the -Xss flag). Sometimes it cause stack overflow with 3 characters. My instructor specifically told me that I shouldn't do it - so I think we should find another smarter method than just going on all of the possible characters from the end of the string.. – Oz Edri May 30 '16 at 23:51

0 Answers0