I am making pasword cracking program(webster dictionary comparing and finding matches) as a school assigment. It is pipeline architecture using threads and bounded buffers. First question would be:
Why it is even slower than centralized pasword cracker even though it is using more threads(one for reading from file-because it is fast process, one for making variations- because it is still faster than 3x encrypting thread, 3 threads for encrypting- because it is very slow process and finnaly one thread for comparing)?
Why when i add 4th thread for encrypting there is no Build successful written in the end of the program when threads finish.
Thank you very much for any answer if need something e.g. my experiments just ask.
CODE: Encrypting class
package passwordcracking;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Encrypt implements Runnable {
private static final Logger LOGGER = Logger.getLogger("passwordCracker");
private final Buffers<String> bufferTakeFrom;
private final Buffers<PairEncPWandClearPW> bufferPutTo;
String possiblePassword;
private MessageDigest messageDigest;
/**
*
* @param bufferTakeFrom
*/
public Encrypt(Buffers<String> bufferTakeFrom, Buffers<PairEncPWandClearPW>
bufferPutTo)
{
this.bufferTakeFrom = bufferTakeFrom;
this.bufferPutTo = bufferPutTo;
try {
messageDigest = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException ex) {
LOGGER.log(Level.SEVERE, ex.getMessage());
throw new RuntimeException(ex);
}
}
@Override
public void run() {
do {
possiblePassword = bufferTakeFrom.take();
EncryptSingleWord(possiblePassword);
} while (!possiblePassword.equals("-1"));
}
private void EncryptSingleWord(final String possiblePassword) {
byte[] digest = null;
try {
digest = messageDigest.digest(possiblePassword.getBytes());
PairEncPWandClearPW pair = new PairEncPWandClearPW(digest, possiblePassword);
bufferPutTo.put(pair);
} catch (Exception ex) {
System.out.println("Exception: " + ex);
System.out.println("possible password bytes: " + possiblePassword.getBytes());
System.out.println("password:" + possiblePassword);
}
}}
Making variations class:
package passwordcracking;
import utilities.StringUtilities;
/**
*
* @author zatokar
*/
public class MakeVariations implements Runnable {
Buffers<String> bufferTakeFrom;
Buffers<String> bufferPutTo;
String dictionaryEntry;
public MakeVariations(Buffers<String> bufferTakeFrom, Buffers<String> bufferPutTo) {
this.bufferTakeFrom = bufferTakeFrom;
this.bufferPutTo = bufferPutTo;
}
@Override
public void run() {
do {
dictionaryEntry = bufferTakeFrom.take();
makeVariations(dictionaryEntry);
if (dictionaryEntry.equals("-1")) {
System.out.println("Make variations thread finished.");
}
} while (!dictionaryEntry.equals("-1"));
}
public void makeVariations(final String dictionaryEntry) {
final String possiblePassword = dictionaryEntry;
bufferPutTo.put(dictionaryEntry);
final String possiblePasswordUpperCase = dictionaryEntry.toUpperCase();
bufferPutTo.put(possiblePasswordUpperCase);
final String possiblePasswordCapitalized = StringUtilities.capitalize(dictionaryEntry);
bufferPutTo.put(possiblePasswordCapitalized);
final String possiblePasswordReverse = new StringBuilder(dictionaryEntry).reverse().toString();
bufferPutTo.put(possiblePasswordReverse);
for (int i = 0; i < 100; i++) {
final String possiblePasswordEndDigit = dictionaryEntry + i;
bufferPutTo.put(possiblePasswordEndDigit);
}
for (int i = 0; i < 100; i++) {
final String possiblePasswordStartDigit = i + dictionaryEntry;
bufferPutTo.put(possiblePasswordStartDigit);
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 100; j++) {
final String possiblePasswordStartEndDigit = i + dictionaryEntry + j;
bufferPutTo.put(possiblePasswordStartEndDigit);
}
}
}
}
Buffers class:
package passwordcracking;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author zatokar
*/
public class Buffers <T>{
final Queue<T> ll = new LinkedList<>();
int capacity=500000;
public synchronized T take(){
while (ll.isEmpty()) {
try {
// System.out.println("empty");
wait();
} catch (InterruptedException ex) {
Logger.getLogger(Buffers.class.getName()).log(Level.SEVERE, null, ex);
}
}
T element = ll.remove();
notifyAll();
return element;
}
public synchronized void put(T element) {
while (isFull()) {
try {
// System.out.println("full "+element);
wait();
} catch (InterruptedException e) {
}
}
ll.add(element);
notifyAll();
}
public boolean isFull(){
return (ll.size()==capacity);
}
public boolean isEmpty(){
if (ll.isEmpty()){
return true;
}
else{
return false;}
}
}
Comparing class:
package passwordcracking;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Compare implements Runnable {
Buffers<PairEncPWandClearPW> bufferTakeFrom;
final List<UserInfo> userInfos;
byte[] digest;
PairEncPWandClearPW pair;
String possiblePassword;
public Compare(Buffers<PairEncPWandClearPW> bufferTakeFrom) throws IOException {
this.bufferTakeFrom = bufferTakeFrom;
userInfos = PasswordFileHandler.readPasswordFile("passwords.txt");
}
@Override
public void run() {
do {
pair=bufferTakeFrom.take();
possiblePassword = pair.getClearPW();
digest = pair.getEncryptedPW();
List<UserInfoClearText> list = checkSingleWord(userInfos, digest,
possiblePassword);
if (!list.isEmpty()) {
System.out.println(list);
}
if (possiblePassword.equals("-1")) {
System.out.println("Comparing thread finished.");
final long endTime = System.currentTimeMillis();
final long usedTime = endTime - PasswordCracking.startTime;
System.out.println("Used time: " + usedTime / 1000 + " seconds = " +
usedTime / 60000.0 + " minutes");
}
} while (!possiblePassword.equals("-1"));
}
private List<UserInfoClearText> checkSingleWord(final List<UserInfo> userInfos, final
byte[] digest, final String possiblePassword) {
final List<UserInfoClearText> results = new ArrayList<UserInfoClearText>();
for (UserInfo userInfo : userInfos) {
if (Arrays.equals(userInfo.getEntryptedPassword(), digest)) {
results.add(new UserInfoClearText(userInfo.getUsername(),
possiblePassword));
}
}
return results;
}
}