带有C 线的平行字典饼干

Parallel dictionary cracker with c++ threads

本文关键字:字典 饼干 带有      更新时间:2023-10-16

我正在学习更好地使用C 中的线程,这是我的学期分配。我正在尝试创建一个相当简单的字典饼干程序,该程序获取.txt文件并在向量中复制每个单词。向量分为相等的"扇区"(每个扇区的单词数(,以便平行。然后,程序启动将作为参数2迭代器的线程,指向扇区的开始和结束。每个线程构造时,都会在上一个线程之后立即处理该扇区。

因此,线程函数将遍历矢量扇区的每个单词之间的开始和结束迭代器之间,计算它的哈希,并根据我需要破解的密码进行检查。当迭代器指向的特定单词时,我正在使用Mutex,尽管我不确定这是否是正确的方法。

目前,我的问题是我遇到了2个编译错误:

错误C2672'std :: Invoke':找到dictionaryCrackerec d: program microsoft Visual Studio 14.0 vc include unce

错误C2893无法专业化功能模板'Unknown-Type std :: Invoke(_callable&&&&_ type&&&&&&&& ...(thr xthread 240

,我不知道它们的准确来自哪一行,以及如何解决它。我在网上研究了各种"调用"问题,但我要么不了解它们,要么似乎与类成员功能有关的电话和类似的内容有关,虽然我什至还没有课程。p>那是理论,这是我主要的实际代码:

#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <mutex>
#include <fstream>
#include <chrono>
#include <Windows.h>
#include <assert.h>
#include <opensslmd5.h>
using namespace std;
//determine the best number of threads based on hardware
const int PC_THREADS_NUM = thread::hardware_concurrency();
mutex password_mutex;
int main()
{
    vector<string> passwdVector;
    vector<string>::const_iterator beginIter, endIter;
    passwdVector.reserve(18000);
    //code here that loads words from .txt file into passwdVector
    string userPassword = "";
    cout << "please insert the password that you'd like to crack: ";
    cin >> userPassword;
    //splitting the vector into sections to parallelize
    int sectionLength = passwdVector.size() / PC_THREADS_NUM;
    beginIter = passwdVector.begin();
    endIter = beginIter + sectionLength;
    vector<thread*> sliceHashingThreads;
    for (int i = 0; i < PC_THREADS_NUM; i++)
    {
        sliceHashingThreads.push_back(new thread(sliceHashCompare, std::ref(passwdVector), userPassword, beginIter, endIter, i));
        beginIter = endIter + 1;
        endIter += sectionLength;
    }
    for (int i = 0; i < sliceHashingThreads.size(); i++)
    {
        sliceHashingThreads[i]->join();
    }
    system("PAUSE");
    return 0;
}

这是slicehashcoompare函数:

    void sliceHashCompare(vector<string>& passwordList, string& password, vector<string>::const_iterator beginIter, vector<string>::const_iterator endIter, int& threadID)
{
    string vectorElement = "", hashedElement = "";
    bool isPassFound = false;
    while (isPassFound != true)
    {
        for (; beginIter <= endIter; ++beginIter)
        {
            password_mutex.lock();
            vectorElement = *beginIter;
            password_mutex.unlock();
            cout << threadID << " is processing word: " << vectorElement << endl;
            //Sleep(100);
            hashedElement = md5Hash(vectorElement);
            if(hashedElement == md5Hash(password))
            {
                isPassFound = true;
                cout << "The password was found! " << password << endl;
                cout << "Hash value: " << hashedElement << endl;
            }
        }
        if(isPassFound == false)
        {
            cout << "Password not found in the dictionary" << endl;
            break;
        }
    }
}

找到密码时,我认为我需要一个有条件的变量,以阻止所有其他线程。我正在考虑的另一件事是稍后实施农民/工人系统,这将使矢量分为更小的部门,并有一系列任务,以便在完成后继续工作。但是目前,我坚持使用8个线程(Thread :: Hartware_concurrency(,并且有些运行良好,并且我只会进行改进。但是,我想学习的任何技巧,建议和可能的解释都非常感谢。

真的希望有人能解释我出了什么问题,并使我了解如何解决它以及为什么。非常感谢您的任何帮助!

我可以看到两个主要问题 - 您无法复制std ::线程,但是您可以移动它,因此将其移动到矢量

sliceHashingThreads.push_back(
           std::move(new thread(sliceHashCompare,
                                std::ref(passwdVector),
                                userPassword,
                                beginIter,
                                endIter,
                                i)));

另外,请注意,如果您只是尝试调用您的功能,

sliceHashCompare(std::ref(passwdVector), userPassword, beginIter, endIter, 0);

您还会遇到错误 - 因为将ThreadID作为参考,如果将其更改为int threadID,则可以。

vs给出了"用户友好"错误列表,但是如果您查看完整的输出(在视图|输出下查找(如果尚未打开,则在提及您的代码之前拖动。

现在应该编译和链接。您还有其他检验。谁将删除您的线程?参见例如最好的C 11存储指针向量的方法


当然,您无需将指针移至线程;问题是int &(而不是删除指针(。

您可以使用std::move

使用std::vector<std::thread>
sliceHashingThreads.emplace_back(sliceHashCompare, 
       std::ref(passwdVector),
       userPassword, beginIter, endIter, i);

您也可以将std::ref(i)用于最后一个参数,以避免更改sliceHashCompare函数。