我有一个字符串的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的学术研究。
答案 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的递归上加上最大值,以便在可预见的将来某个时间结束