蛮力java递归密码破解

Brute-Force java recursive password crack

我接到了另一项家庭作业,我为此绞尽脑汁了一个星期: 我得到了一个 class,它只在给定的长度上创建 a-z 的密码。

public class Password {
private String _password = "";

// Constructor that generates a 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);
    }
}

//Method that compares a given string to the password
public boolean isPassword(String st) {
    return st.equals(this._password);
}
}  

规则:

这是我到目前为止得到的:

public static String findPassword(Password p, int length) {
    String pswd= "";
    char char2Check = 'a';

    if (length == 0) {
        return "";
    }
    else {
        return findPassword(p,length, pswd, char2Check);
    }
}

public static String findPassword(Password p,int length, String pswd, char char2Check) {
    if (pswd.length() < length) {
            pswd+= char2Check;
            pswd = findPassword(p,length,pswd,char2Check);
        if (pswd.length() < length) {
            if (pswd.length() == 0) {
                if (char2Check == 'z') {
                    return pswd;
                }
                if (char2Check < 'z') {
                    char2Check++;
                    pswd += char2Check;
                    return findPassword(p, length, pswd, char2Check);
                }
            }
            else {
                if (char2Check == 'z') {
                    return pswd.substring(0, pswd.length() - 1);
                }
                if (char2Check < 'z') {
                    pswd = pswd.substring(0, pswd.length() - 1);
                    char2Check++;
                    pswd += char2Check;
                    return findPassword(p, length, pswd, char2Check);
                }
            }
        }
    }
    if (pswd.length() == length) {
        System.out.println(pswd);
        if (p.isPassword(pswd)) {
            return pswd;
        }
        if (char2Check < 'z') {
            pswd = pswd.substring(0, pswd.length() - 1);
            char2Check++;
            pswd+= char2Check;
            return findPassword(p,length,pswd,char2Check);
        }
        if (char2Check == 'z'){
            return pswd.substring(0, pswd.length() - 1);
        }
    }
    return pswd;
}

问题是:

如果第一个字符是 'r' 它不会检查它后面的 a、b 或 c,它会直接到 s、t、u...

还有一些问题,但是一旦这个问题消失了,我想剩下的就更容易解决了..

这里是输出的粘贴: http://pastebin.com/CK9AyKUi

希望有人能帮助我:)

您为本应很简单的事情费尽心思:生成所有长度为 n 且仅包含 a-z 字符的字符串。

关于性能的注意事项:当您想执行大量 append 和删除字符时,请使用 StringBuilder 而不是 String。字符串是不可变的,因此它们会在您的代码中被一次又一次地复制。

现在,关于递归,您只需考虑两件事:您的一般情况是什么?你的停止条件是什么?

这里,停止条件很简单:真实密码和当前试用密码长度相同。如果试验正确,那么return就可以了;否则在递归中上升。第二次停止条件:当前前缀所有可能都试过了没有匹配,则递归上去

一般情况也很简单:给定当前前缀,尝试附加每个可能的字母 a-z 并添加一级递归。

现在,您可能想利用这些线索再试一次(提示:重新开始比尝试修复当前代码更容易)。我的解决方案如下,但您可以提出自己的解决方案:

public static String findPassword(Password p, int length) {
    return findPassword(p,length, new StringBuilder());
}

public static String findPassword(Password password, int length, StringBuilder str) {
    // Stop condition, password and trial have same length
    if (length == str.length()) {
        if (password.isPassword(str.toString())) {
            return str.toString();
        } else {
            return "";
        }
    }

    String s;

    for (char c = 'a'; c <= 'z'; c++) {
        // Add a new character to the given prefix
        str.append(c);
        // Try to find a password for the new prefix
        s = findPassword(password, length, str);
        if (!s.equals("")) {
            return s;
        }
        // Didn't work out, remove the character
        str.deleteCharAt(str.length()-1);
    }
    // All chars have been tried without success, go up one level
    return "";
}

我不会给你解决方案。但是假设字母表是 "abc" 并且你想找到长度为 3 的密码,你必须这样编程:

a -> aa -> aaa 
|     |      | 
|     |    aab 
|     |      | 
|     |    aac 
|     |        
|    ab -> aba 
|     |      | 
|     |    abb 
|     |      | 
|     |    abc 
|     |        
|    ac -> aca 
|            | 
|          acb 
|            | 
|          acc 
|              
b -> ba -> baa 
|     |      | 
|     |    bab 
|     |      | 
|     |    bac 
|     |        
|    bb -> bba 
|     |      | 
|     |    bbb 
|     |      | 
|     |    bbc 
|     |        
|    bc -> bca 
|            | 
|          bcb 
|            | 
|          bcc 
|              
c -> ca -> caa 
      |      | 
      |    cab 
      |      | 
      |    cac 
      |        
     cb -> cba 
      |      | 
      |    cbb 
      |      | 
      |    cbc 
      |        
     cc -> cca 
             | 
           ccb 
             | 
           ccc

您必须检查每个递归步骤的 2 条路径。

  • ->,密码不够长,加'a'试试
  • |,它递增最后一个字符,只要它不是字母表的最后一个。

这两条路径都有一个停止条件,您必须注意:密码长度和字母长度。

 private static boolean findPassword(Password p, String pswd, int length) {

    if (length == pswd.length()) {
        if (p.isPassword(pswd))
            System.out.println(pswd);
        return p.isPassword(pswd);

    }

    String alpha = "abcdefghijklmnopqrstuvwxyz";
    for (int i = 0; i < alpha.length(); i++) {
        if (findPassword(p, pswd + alpha.charAt(i), length)) 
            return true;
    }
    return p.isPassword(pswd);
}

首先非常感谢!

你的代码给了我一些好主意 为您修好了:)

我已经更正了你的代码,它的工作非常完美

这里是:

  public static String findPassword(Password p,int length)
  {
      // string and char to be input into the overloading method
      String pswd= "";
      char char2Check = 'a';

      // Checking if the length of the password is 0 so its null
      if (length == 0)
      {
          return "";
      }
      else{
          // going to the overloading method to find the password
          return findPassword(p,length, pswd, char2Check);
      }
  }

  public static String findPassword(Password p,int length, String pswd, char      char2Check)
  {

    // Checking if the length of the password finder is less then the length of the 
    // password we add more chars until they are the same length to check if they're equal
    if (pswd.length() < length)
    {
        pswd+= char2Check;
        pswd = findPassword(p,length,pswd,char2Check);
        char2Check = pswd.charAt(pswd.length() - 1);
        if (pswd.length() < length)
        {
            if (pswd.length() == 0)
            {
                if (char2Check == 'z')
                {
                    return pswd;
                }
                if (char2Check < 'z')
                {
                    char2Check++;
                    pswd += char2Check;
                    return findPassword(p, length, pswd, char2Check);
                }
            }else{
                if (char2Check == 'z')
                {
                    return pswd.substring(0, pswd.length() - 1);
                }
                if (char2Check < 'z')
                {
                    char2Check = pswd.charAt(pswd.length() - 1);
                    pswd = pswd.substring(0, pswd.length() - 1);
                    char2Check++;
                    pswd += char2Check;
                    return findPassword(p, length, pswd, 'a');
                }
            }
        }
    }
    // Checking if the password finder length is the same as the original password
    if (pswd.length() == length)
    {
        System.out.println(pswd);
        // Checking if the two password match, if so we return the password finder.
        if (p.isPassword(pswd))
        {
            return pswd;
        }
        // Checking if the char is not the last char -> z
        if (char2Check < 'z')
        {
            pswd = pswd.substring(0, pswd.length() - 1);
            char2Check++;
            pswd+= char2Check;
            return findPassword(p,length,pswd,char2Check);
        }
        if (char2Check == 'z')
        {
            return pswd.substring(0, pswd.length() - 1);
        }
    }
    return pswd;
}