使用#pragma omp paralle for

问题描述 投票:0回答:1

我正在使用 C++ 和 OMP 库练习 2 个线程的暴力破解:

#include <iomanip>
#include <sstream>
#include <openssl/md5.h>
#include <cstring> 
#include <iostream>
#include <omp.h>
#define NUM_THREADS 2

int main() {
    unsigned char digest[MD5_DIGEST_LENGTH];
    std::cout << "Enter hash: ";
    std::string target;
    std::cin >> target; 
    char password[11] = "0000000000";
    bool flag = true;
    std::ostringstream password_stream;
    std::ostringstream hex_hash;
    while (flag) {
        #pragma omp parallel for num_threads(NUM_THREADS)
        for (unsigned long long i = 0; i <= 9999999999ULL; ++i) {
    password_stream <<  std::setfill('0') << std::setw(10)  << i;
        std::string  password_str = password_stream.str();

        MD5(reinterpret_cast<const unsigned char*>(password_str.c_str()), password_str.length(), digest);
    
        for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
            #pragma omp critical
            hex_hash << std::hex << std::setw(2) << std::setfill('0') << (int)digest[i];
        }
        std::string hex_hash_str = hex_hash.str();

    //std::cout << omp_get_thread_num() << std::endl;
        if (hex_hash_str == target) {
    #pragma omp critical
            std::cout << "Orginal password: " <<  password_str << std::endl;
            flag = false;
        }

        if (i % 100000 == 0) {
            std::cout << "Wrong: " << password_str << " " << hex_hash_str << " Trying again..." << std::endl;
        }
        }
    }

    return 0;
}

但是他们要么试图写入一个流,要么我得到了错误的十六进制数字哈希计算,或者是分段错误或总线错误。

我正在尝试使用 #pragma omp critical 以避免线程写入一个流。另外,我尝试在 #pragma omp parallel for 之前将带有密码和十六进制哈希的变量放入全局变量中。所有这些都会导致哈希计算错误或分段错误。

密码由10位数字组成

c++ parallel-processing openssl segmentation-fault openmp
1个回答
0
投票

我认为有几个问题:

  • password_stream
    hex_hash
    不是线程安全的

  • std::ostringstream
    不是线程安全的

  • 变量

    flag
    password_stream
    由所有线程共享。

  • password_stream
    hex_hash
    digest
    未本地化到线程

没有测试自己,但试试这个:

while (flag) {
    #pragma omp parallel for num_threads(NUM_THREADS)
    for (unsigned long long i = 0; i <= 9999999999ULL; ++i) {
        std::ostringstream password_stream;  // moved inside the loop
        password_stream << std::setfill('0') << std::setw(10) << i;
        std::string password_str = password_stream.str();

        unsigned char local_digest[MD5_DIGEST_LENGTH];  // changed to local
        MD5(reinterpret_cast<const unsigned char*>(password_str.c_str()), password_str.length(), local_digest);

        std::ostringstream hex_hash;  // moved inside the loop
        for (int j = 0; j < MD5_DIGEST_LENGTH; ++j) {
            hex_hash << std::hex << std::setw(2) << std::setfill('0') << (int)local_digest[j];
        }
        std::string hex_hash_str = hex_hash.str();

        if (hex_hash_str == target) {
            #pragma omp critical
            {
                std::cout << "Original password: " << password_str << std::endl;
                flag = false;
            }
        }

        if (i % 100000 == 0) {
            #pragma omp critical
            {
                std::cout << "Wrong: " << password_str << " " << hex_hash_str << " Trying again..." << std::endl;
            }
        }

        #pragma omp flush(flag)  // improved
        if (!flag) break;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.