如何用多线程加速代码?

baubqpgj  于 2021-07-11  发布在  Java
关注(0)|答案(1)|浏览(290)

我在java中创建了一个密码破解程序,可以破解文本文件列表中的密码。然后,它生成一个字典,其中包含以下对:散列的单词和原始单词。我正在寻找一种加速程序的方法,让它从文件中读取所有单词,然后使用多线程生成哈希。如何将单词列表分解成四个独立的分区,然后在createdictionary方法中对其进行多线程操作?到目前为止,我掌握的情况如下:

public class Main {
    private static final String FNAME = "words.txt";
    private final static String PASSWDFNAME = "passwd.txt";
    private static Map<String, String> dictionary = new HashMap<>();

    public static void main(String[] args) {
        // Create dictionary of plain / hashed passwords from list of words
        System.out.println("Generating dictionary ...");
        long start = System.currentTimeMillis();
        createDictionary(FNAME);
        System.out.println("Generated " + dictionary.size() + " hashed passwords in dictionary");
        long stop = System.currentTimeMillis();
        System.out.println("Elapsed time: " + (stop - start) + " milliseconds");

        // Read password file, hash plaintext passwords and lookup in dictionary
        System.out.println("\nCracking password file ...");
        start = System.currentTimeMillis();
        crackPasswords(PASSWDFNAME);
        stop = System.currentTimeMillis();
        System.out.println("Elapsed time: " + (stop - start) + " milliseconds");
    }

    private static void createDictionary(String fname) {
        // Read in list of words
        List<String> words = new ArrayList<>();
        try (Scanner input = new Scanner(new File(fname));) {
            while (input.hasNext()) {
                String s = input.nextLine();
                if (s != null && s.length() >= 4) {
                    words.add(s);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("File " + FNAME + " not found");
            e.printStackTrace();
            System.exit(-1);
        }

        // Generate dictionary from word list
        for (String word : words) {
            generateHashes(word);
        }
    }

    private static void crackPasswords(String fname) {
        File pfile = new File(fname);
        try (Scanner input = new Scanner(pfile);) {
            while (input.hasNext()) {
                String s = input.nextLine();
                String[] t = s.split(",");
                String userid = t[0];
                String hashedPassword = t[1];
                String password = dictionary.get(hashedPassword);
                if (password != null) {
                    System.out.println("CRACKED - user: "+userid+" has password: "+password);
                }
            }
        } catch (FileNotFoundException ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
            System.exit(-1);
        }
    }

    private static void generateHashes(String word) {
        // Convert word to lower case, generate hash, store dictionary entry
        String s = word.toLowerCase();
        String hashedStr = HashUtils.hashPassword(s);
        dictionary.put(hashedStr, s);
        // Capitalize word, generate hash, store dictionary entry
        s = s.substring(0, 1).toUpperCase() + s.substring(1);
        hashedStr = HashUtils.hashPassword(s);
        dictionary.put(hashedStr, s);
    }
}
bmvo0sr5

bmvo0sr51#

很简单,看看这个:

public static void main(String[] args) {
    List<String> words = new ArrayList<>();
    List<Thread> threads = new ArrayList<>();

    int numThreads = 4;
    int threadsSlice = words.size() / numThreads;

    for(int i = 0; i < numThreads; i++) {
        Thread t = new Thread(new WorkerThread(i * threadsSlice, (i + 1) * threadsSlice, words));
        t.start();
        threads.add(t);
    }

    threads.forEach(t -> {
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}

static class WorkerThread implements Runnable {
    private final int left;
    private final int right;
    private final List<String> words;

    public WorkerThread(int left, int right, List<String> words) {
        this.left = left;
        this.right = right;
        this.words = words;
    }

    @Override
    public void run() {
        for (int i = left; i < right; i++) {
            generateHashes(words.get(i));
        }
    }
}

这段代码创建4个线程,每个线程扫描列表的一个分区,并应用 generateHashes 分区中所有单词的方法。
你可以把 words 在堆内存中,以避免通过构造函数param将其传递给每个线程。
还要确保使用 ConcurrentMap 为了你的字典 generateHashes 方法

相关问题