You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程密码破解程序优化求助:指定线程数分配任务及终止问题

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 07:50:21