我正在制作密码破解程序(韦伯斯特词典比较和查找匹配项)作为学校作业。它是使用线程和有界缓冲区的管道架构。第一个问题是:
为什么即使它使用更多线程(一个用于从文件读取 - 因为它是快速的过程,一个用于进行变化 - 因为它仍然比 3x 加密线程快,3 个用于加密的线程 - 因为它比集中式密码破解器还要慢)这是一个非常缓慢的过程,最后只有一个线程进行比较)?
为什么当我添加第 4 个加密线程时,当线程完成时,程序末尾没有写入成功的构建。
非常感谢您的任何回答,如果需要一些东西,例如我的实验只是问。
代码:加密类
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);
}
}}
制作变化类:
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);
}
}
}
}
缓冲器类:
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;}
}
}
类比:
包密码破解;
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;
}
}