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

C++实现密码破解时如何自动化嵌套循环支持任意长度密码

问题说明

编写暴力破解密码程序时,硬编码嵌套循环仅支持固定长度(当前为4位)的密码破解,若要支持更长密码需要反复复制粘贴循环、判断逻辑,代码冗余且维护成本高,需要实现无需硬编码嵌套层数、支持任意指定最大长度密码的破解逻辑。

原有硬编码实现如下:

#include <iostream>
#include <string>
#include <ctime>  


using namespace std;

const char alphanum[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&* ";
const string pw = "0000";
bool cracked = false;
int tries = 0;
const int pwLength = pw.length();
string crack();
string guess="0";
const int maxLen = 30;

int main()
{
    clock_t begin, end;
    double time;
    begin = clock();

    string crackedPassword = crack();
        
    end = clock();

    time = double(end - begin) / (double)CLOCKS_PER_SEC;
    cout << "The password is: " << crackedPassword << "   The program checked a total of " << tries << " possibilites and took " << time << " seconds to crack the password!";

    return 0;
}


string crack() {
    int index = 0;
    int repeat = 0;
    while (!cracked) {
        for (int i = 0; i < 71; i++) {
            tries++;
            guess[index] = alphanum[i];
            cout << "Trying: " << guess << endl;
            if (repeat > 0) {
                for (int i = 0; i < 71; i++) {
                    tries++;
                    guess.push_back(alphanum[i]);
                    cout << "Trying: " << guess << endl;
                    if (repeat > 1) {
                        for (int i = 0; i < 71; i++) {
                            tries++;
                            guess.push_back(alphanum[i]);
                            cout << "Trying: " << guess << endl;
                            if (repeat > 2) {
                                for (int i = 0; i < 71; i++) {
                                    tries++;
                                    guess.push_back(alphanum[i]);
                                    cout << "Trying: " << guess << endl;
                                    if (guess == pw) {
                                        cracked = true;
                                        break;
                                    }
                                    else {
                                        guess.pop_back();
                                    }
                                }
                            }
                            if (guess == pw) {
                                cracked = true;
                                break;
                            }
                            else {
                                guess.pop_back();
                            }
                        }
                    }
                    if (guess == pw) {
                    cracked = true;
                    break;
                }
                    else {
                        guess.pop_back();
                    }
                }
            }
            if (guess == pw) {
                cracked = true;
                break;
            }
        }
        repeat++;
    }
    return guess;
}
实现思路

硬编码嵌套循环本质是固定深度的遍历,要支持可变深度,用递归回溯即可实现,不需要手动写多层循环:

  • 按密码长度从小到大枚举(从1位到设定的最大长度),和原有逻辑一致
  • 递归时维护当前拼接的猜测串,每次尝试往串末尾追加一个字符集中的字符
  • 若当前串长度等于当前枚举的密码长度,就和目标密码做比对:匹配则直接返回结果,不匹配则回退最后一位字符,尝试下一个可选字符
  • 全程不需要硬编码循环层数,修改最大长度参数即可支持对应长度的密码破解

另外原代码中写死的71是魔法数字,实际可以通过字符集数组自动计算长度,避免后续修改字符集时漏改数值导致bug。

修正后可运行代码
#include <iostream>
#include <string>
#include <ctime>
using namespace std;

const char alphanum[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&* ";
const int charsetLen = sizeof(alphanum) - 1; // 自动计算字符集长度,去掉末尾结束符'\0'
const string targetPw = "0000a"; // 可修改为任意长度的测试密码
bool cracked = false;
int tries = 0;
const int maxLen = 30;
string result;

// 递归回溯函数
void backtrack(string& currentGuess, int targetLen) {
    if (cracked) return; // 已经找到密码直接返回
    // 长度达到当前目标长度,做比对
    if (currentGuess.size() == targetLen) {
        tries++;
        // 调试时可打开打印,正式跑建议关闭,IO开销极高
        // cout << "Trying: " << currentGuess << endl;
        if (currentGuess == targetPw) {
            cracked = true;
            result = currentGuess;
        }
        return;
    }
    // 遍历所有可选字符
    for (int i = 0; i < charsetLen; i++) {
        if (cracked) return;
        currentGuess.push_back(alphanum[i]);
        backtrack(currentGuess, targetLen);
        currentGuess.pop_back(); // 回溯,撤销本次选择
    }
}

string crack() {
    string guess;
    // 从小到大枚举密码长度
    for (int len = 1; len <= maxLen; len++) {
        if (cracked) break;
        guess.clear();
        backtrack(guess, len);
    }
    return result;
}

int main()
{
    clock_t begin, end;
    double timeCost;
    begin = clock();

    string crackedPassword = crack();
        
    end = clock();

    timeCost = double(end - begin) / (double)CLOCKS_PER_SEC;
    cout << "The password is: " << crackedPassword 
         << "   The program checked a total of " << tries 
         << " possibilites and took " << timeCost << " seconds to crack the password!";

    return 0;
}
注意事项
  • 暴力破解的时间复杂度随密码长度呈指数级增长:以当前71个字符的字符集计算,6位密码就有71^6 ≈ 1.28*10^11种组合,普通单线程程序跑可能需要数天,更长的密码靠单线程暴力破解基本不现实。
  • 当前递归实现的最大深度为maxLen,即使设为30层也完全不会触发栈溢出,无需额外优化;如果偏好非递归写法,也可以用“类数字进位”的迭代逻辑实现相同效果,性能基本一致。
  • 每次尝试都打印猜测内容会产生极大的IO开销,严重拖慢运行速度,非调试场景建议移除打印逻辑。

内容的提问来源于stack exchange,提问作者Simply

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 10:15:37