想出一个可变长度的字符串?

时间:2011-05-15 14:10:22

标签: java string recursion md5

我有一个字符串的MD5哈希值,存储为String。我正在写一个小程序,通过蛮力找出原始字符串。

我想循环遍历char

的子集

以下代码适用于String.length() == 0

我无法弄清楚如何编辑此代码以使用可变长度String s。我觉得我在递归时走的正确,但不能再进一步了。

我有以下代码:

    public void attempt(String initial, String md5) {

    for (char c = ' '; c < '~'; ++c) {
        attempt = initial + Character.toString(c);
        generatedMd5 = generateMD5(attempt);
        System.out.println(attempt);
        if (hashesMatch(md5, generatedMd5)) {
            break;
        } else attempt(attempt, md5);
    }
}

注意:我应该提到这是关于MD5的学术研究。

2 个答案:

答案 0 :(得分:6)

您正在进行“Depth first”搜索(并且无限深度!),如果您不添加深度检查,这几乎可以保证失败(耗尽您的筹码)。

应该更好可能想做Breadth first search:你的循环首先应该尝试所有导致添加角色的组合,然后,如果没有成功,尝试用每个增强字符串递归调用该方法。

在任何情况下,您都应该添加一些深度检查。

编辑:两次思考,我不太确定你不应该先坚持深度。对于小深度和组合(字符范围),宽度优先只能在这里进行。可能的实施

  // Breadth first returns null if not found
  public String bruteforce(List<String> prefixes, String md5,int availdepth) {
    if(availabledepth<0) return null;
    List<String> newprefixes = new ArrayList<String>();
    for(String prefix : prefixes) {
        for (char c = ' '; c < '~'; ++c) {
          String attempt = prefix + Character.toString(c);
          generatedMd5 = generateMD5(attempt);
          if (hashesMatch(md5, generatedMd5)) 
            return attempt;
          newprefixes.add(attempt);
       }
    }
    // no success in this level go for next
    return bruteforce(newprefixes,md5,availddepth-1);
  }


  // Depth first - returns null if not found
  public String bruteforce(String prefix, String md5,int availdepth) {
    if(availdepth <= 0) return null;
    for (char c = ' '; c < '~'; ++c) {
          String attempt = prefix + Character.toString(c);
          if (hashesMatch(md5, generateMD5(attempt))) 
            return attempt;
          String res = bruteforce(attempt, md5, availdepth-1);
          if(res != null) return res;
       }
    return null;
  }

答案 1 :(得分:1)

你们中的第一个人不会返回结果...

第二,你在无限空间中首先做深度(它永远不会结束......)

public String attempt(String initial, String md5,int depth) {
    if(depth < 0)return null;//failed backtrack
    for (char c = ' '; c < '~'; ++c) {
        attempt = initial + Character.toString(c);
        generatedMd5 = generateMD5(attempt);
        System.out.println(attempt);
        if (hashesMatch(md5, generatedMd5)) {
            return attempt;//success
        } else {
            String res = attempt(attempt, md5,depth-1);
            if(res!=null)return res;
        }
    }
}

这是一个有限的深度,这意味着它不会比深度更进一步递归(并且当它找不到任何东西时返回null

以下内容可用于遍历深度10000的整个空间

String attempt(String initial,String md5){
    for(int i = 5;i<10000;i++){
        String res = attempt(initial,md5,i);
        if(res!= null)return res;
    }
    return null;//let's not go overboard on recursion
}

我在10000的递归上加上最大值,以便在可预见的将来某个时间结束