我正在使用 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位数字组成
我认为有几个问题:
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;
}
}