package model;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Arrays;
import org.apache.log4j.Logger;
import delegate.ProgressDisplay;
public class PasswordCracker {
private final String key3Path;
public static final int MAX_WORDLENGTH = 5;
private static long wordsTried;
private final static Logger logger = Logger
.getLogger(PasswordCracker.class);
private final ProgressDisplay progressDisplay;
private boolean running;
public PasswordCracker(String key3Path, ProgressDisplay progressDisplay) {
this.key3Path = key3Path;
this.progressDisplay = progressDisplay;
}
public String recoverByWordList(String wordlistPath) {
this.running = true;
wordsTried = 0;
try (BufferedReader reader = Files.newBufferedReader(new File(
wordlistPath).toPath(), StandardCharsets.ISO_8859_1)) {
Key3DBParser parser = new Key3DBParser(key3Path);
parser.parse();
String word = null;
while ((word = reader.readLine()) != null) {
handleWordCount();
if (!running) {
break;
}
if (parser.isPassword(word)) {
logger.info("found password: " + word);
return word;
}
}
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
return null;
}
public String recoverByBruteforcing(int wordlength) {
this.running = true;
wordsTried = 0;
try {
Key3DBParser parser = new Key3DBParser(key3Path);
parser.parse();
String result = bruteforce(getAlphabet(), wordlength, parser);
if (result != null) {
return result;
}
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
return null;
}
public String recoverByBruteforcing() {
this.running = true;
wordsTried = 0;
try {
Key3DBParser parser = new Key3DBParser(key3Path);
parser.parse();
for (int i = 1; i <= MAX_WORDLENGTH; i++) {
if (!running) {
break;
}
String result = bruteforce(getAlphabet(), i, parser);
if (result != null) {
return result;
}
}
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
return null;
}
public String bruteforce(char[] alphabet, int wordlength,
Key3DBParser parser) {
final long MAX_WORDS = (long) Math.pow(alphabet.length, wordlength);
final int RADIX = alphabet.length;
for (long i = 0; i < MAX_WORDS; i++) {
if (!running) {
break;
}
int[] indices = convertToRadix(RADIX, i, wordlength);
char[] word = new char[wordlength];
for (int k = 0; k < wordlength; k++) {
word[k] = alphabet[indices[k]];
}
handleWordCount();
if (parser.isPassword(new String(word))) {
logger.info("found password: " + new String(word));
return new String(word);
}
}
return null;
}
private void handleWordCount() {
wordsTried++;
if (wordsTried % 10000 == 0) {
progressDisplay.setNewProgress(wordsTried);
logger.debug("number of passwords tried: " + wordsTried);
}
}
private int[] convertToRadix(int radix, long number, int wordlength) {
int[] indices = new int[wordlength];
for (int i = wordlength - 1; i >= 0; i--) {
if (number > 0) {
int rest = (int) (number % radix);
number /= radix;
indices[i] = rest;
} else {
indices[i] = 0;
}
}
return indices;
}
private char[] getAlphabet() { // TODO make editable alphabets
char[] alphabet = new char[26 * 2];
for (int i = 0; i < 26; i++) {
alphabet[i] = (char) (i + 97);
alphabet[i + 26] = (char) (i + 65);
}
logger.debug("alphabet used for bruteforcing: "
+ Arrays.toString(alphabet));
return alphabet;
}
public void setRunning(boolean b) {
this.running = b;
}
public static long getWordsTried() {
return wordsTried;
}
}