开发者

Figure out a String of variable length?

I have the MD5 hash for a String, stored as a String. I'm writing a small program to find out the original string by brute force.

I'd like to loop through a subset of char.

The code below works for when String.length() == 0.

I can't figure out how to edit this code to work with variable-length Strings. I feel like I'm on the right track with recursion, but can't go any further.

I have the following code:

    public void attempt(String initial, St开发者_运维百科ring 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);
    }
}

Note: I should mention this is for an academic study on MD5.


You are doing a "Depth first" search (and of unlimited depth!), this is almost guaranteed to fail ( exhausting your stack) if you do not add some depth check.

You should probably better might want to do a Breadth first search : your loop should first try all the combinations that results in adding a character, and only then, if no success, try to recursively call the method with each augmented string.

In any case, you should add some depth check, always.

Edited: thinking it twice, I'm not so sure you should not stick with depth first. Breadth first is only rasonable here for small depths and combinations (character ranges). A possible implementation

  // 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;
  }


first of you don't return a result...

second you are doing depth first on a infinite space (it's never going to end...)

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;
        }
    }
}

this is a bounded depth first meaning it won't recurse further than depth (and return null when it can't find anything

the following can be used to go over the entire space up to depth 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
}

I put a max size on the recursion on 10000 to make it end sometime in the foreseeable future

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜