Si ya tienes un password definido y solo tienes que buscarlo es mas fácil que desconociendo este :P si fuese ese el caso se ocuparía otro algoritmo.
Acá te dejo un ejemplo:
public static void main(String[] args) {
String password = "AbC#)34adks)=!das?/dewg5462";
int maxchr = 255;
StringBuilder result = new StringBuilder();
int length = 0;
while(true)
{
if(password.equals(result) || length >= password.length())
break;
for(int i = 0; i <= maxchr; i++)
{
char current = password.charAt(length);
char chrMatch = (char) i;
if(current == chrMatch)
{
result.append(current);
length++;
break;
}
}
}
System.out.println(String.format("result: %s", result));
}
Lo que hago es comprobar carácter por carácter y si coincide lo agrego al resultado hasta que coincida con el password.
EDIT: si el password a descubrir fuera un hash, podría ser encontrado por fuerza bruta con diccionario o sin este.
Acá te dejo un código que hice de ejemplo, hice uso de la librería apache commons codec
para simplificarlo:
class Brute{
private String hash;
private String result;
private ArrayList<Character> allowedChars = new ArrayList<Character>();
private int maxLength = 10;
private int currentLength = 0;
private boolean found = false;
private final long startTime = System.currentTimeMillis();
private long endTime;
Brute(String password)
{
this.hash = password;
// a-z A-Z 0-9 punctuations!
for(int i = 33; i <= 126; i++)
allowedChars.add((char)i);
// extended ascii
for(int i = 128; i <= 255; i++)
allowedChars.add((char)i);
}
public Brute setLength(int length)
{
this.maxLength = length;
return this;
}
public Brute calc()
{
for(int i = 0; i <= this.maxLength; i++)
{
if(this.force("", 0, i))
break;
this.currentLength++;
}
return this;
}
private boolean force(String str, int position, int length)
{
for (char chr : allowedChars)
{
this.showProgress(str + Character.toString(chr));
if (position < length - 1)
{
force(str + Character.toString(chr), position + 1, length);
}
if(this.checkHash(str + Character.toString(chr)))
{
this.found = true;
this.result = str + Character.toString(chr);
}
}
// si queremos conservar recursos D:
/*try {
Thread.sleep(100);
} catch (InterruptedException e)
{
}*/
return this.found;
}
private void showProgress(String str)
{
String find_msg = String.format("buscando en %s caracteres (%s)", this.currentLength, str);
System.out.print("\r" + find_msg);
}
private boolean checkHash(String str)
{
if(DigestUtils.md5Hex(str).equals(this.hash)){
endTime = System.currentTimeMillis();
return true;
}
return false;
}
public void show()
{
System.out.println(new Object(){
@Override
public String toString()
{
if(found)
return String.format(
"\npassword encontrado!: '%s'\ntiempo de busqueda: %d ms\n",
result, (endTime-startTime));
return "\rnot found";
}
});
}
}
Para usarlo:
Brute search = new Brute(DigestUtils.md5Hex("abc"));
search.setLength(5).calc().show();
a mi me tardo 26401 ms
El resultado:
root@ubuntu:/home/white/workspace/java/brute_force/output# java -jar brute.jar
buscando en 3 caracteres (ÿÿÿ)
password encontrado!: 'abc'
tiempo de busqueda: 26401 ms
Habría que pulir mas cosas como por ejemplo:
- hacer uso de hilos
- darle un sleep al bucle
- hacerlo funcional para mas hashes