多线程密码破解程序优化求助:指定线程数分配任务及终止问题
C语言多线程密码破解程序修复方案
问题说明
现有多线程密码破解程序存在两个核心问题:
- 所有线程重复遍历全部密码组合,未实现任务拆分
- 找到匹配密码后无法立即终止程序,需等待所有线程完成遍历
修复后完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <crypt.h> #include <unistd.h> #include <pthread.h> int count = 0; int num_threads = 4; int found = 0; // 标记是否找到密码 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 线程参数结构体 typedef struct { int thread_id; char* salt_and_encrypted; } ThreadArgs; void substr(char *dest, char *src, int start, int length) { memcpy(dest, src + start, length); *(dest + length) = '\0'; } void crack(int thread_id, char *salt_and_encrypted) { int x, y, z; char salt[7]; char plain[7]; char *enc; int start_x, end_x; substr(salt, salt_and_encrypted, 0, 6); // 按线程ID拆分第一个字符的遍历范围 int range = 26 / num_threads; start_x = 'A' + thread_id * range; // 最后一个线程处理剩余的字母 end_x = (thread_id == num_threads - 1) ? 'Z' : start_x + range - 1; for (x = start_x; x <= end_x && !found; x++) { for (y = 'A'; y <= 'Z' && !found; y++) { for (z = 0; z <= 99 && !found; z++) { sprintf(plain, "%c%c%02d", x, y, z); enc = (char *)crypt(plain, salt); pthread_mutex_lock(&mutex); count++; pthread_mutex_unlock(&mutex); if (strcmp(salt_and_encrypted, enc) == 0) { pthread_mutex_lock(&mutex); found = 1; printf("#%-8d%s %s\n", count, plain, enc); pthread_mutex_unlock(&mutex); return; } } } } } void* worker(void* arg) { ThreadArgs* args = (ThreadArgs*)arg; crack(args->thread_id, args->salt_and_encrypted); free(args); return NULL; } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <num_threads>\n", argv[0]); return 1; } num_threads = atoi(argv[1]); if (num_threads <= 0 || num_threads > 26) { printf("Thread count must be between 1 and 26\n"); return 1; } char encrypted_password[] = "$6$AS$07bMLxcKqVbTklYXuFw7alIrQnPfh6.oDeQIZHaud6iaAZj9IgbkPytVlU2nx.H10EGS49uOIoV3m3ZNZF87s0"; pthread_t threads[num_threads]; int i; for (i = 0; i < num_threads; i++) { ThreadArgs* args = malloc(sizeof(ThreadArgs)); args->thread_id = i; args->salt_and_encrypted = encrypted_password; pthread_create(&threads[i], NULL, worker, args); } // 等待直到找到密码或所有线程结束 while (1) { pthread_mutex_lock(&mutex); int is_found = found; pthread_mutex_unlock(&mutex); if (is_found) break; // 检查是否所有线程都已结束 int all_done = 1; for (i = 0; i < num_threads; i++) { if (pthread_kill(threads[i], 0) == 0) { all_done = 0; break; } } if (all_done) break; usleep(10000); // 避免忙等 } // 终止所有剩余线程 for (i = 0; i < num_threads; i++) { if (pthread_kill(threads[i], 0) == 0) { pthread_cancel(threads[i]); } } // 等待线程退出 for (i = 0; i < num_threads; i++) { pthread_join(threads[i], NULL); } printf("%d solutions explored\n", count); pthread_mutex_destroy(&mutex); return 0; }
核心改动说明
1. 任务拆分
- 基于密码的第一个字母(A-Z)拆分任务,将26个字母平均分配给指定数量的线程,每个线程负责一段连续的字母范围
- 通过
ThreadArgs结构体传递线程ID和加密密码,明确每个线程的遍历边界
2. 全局终止逻辑
- 新增全局变量
found,配合互斥锁实现线程安全的状态标记 - 每个线程在三层循环中都检查
found状态,一旦标记为1则立即退出遍历 - 主线程通过循环检测
found状态,发现密码找到后,使用pthread_cancel主动终止所有未完成的线程,避免无效运行
3. 其他细节修复
- 修正原代码中
atoi(argv[1)的语法错误(缺少闭合括号) - 增加线程数合法性检查(1-26之间,因为只有26个大写字母)
- 对
count变量的操作加互斥锁,保证计数准确 - 动态分配线程参数结构体,避免栈内存溢出
内容的提问来源于stack exchange,提问作者simanta
相关产品推荐
相关产品推荐

