我的C++语言蛮力算法有问题



我遇到了一个问题,我要创建一个程序,该程序具有使用 ASCII 表生成随机密码的函数(使用 srand 从 0 到 256 生成随机数,然后将它们类型转换为字符(,另一个函数来显示生成的密码。然后另一个功能使用蛮力方法破解生成的密码。生成密码的功能工作正常,但我遇到的问题是破解密码的功能。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void Generate_Pass(char pass[5])
{
int seed = time(NULL);
srand(seed);
for(int i = 0; i < 5; i++){
pass[i] = rand()%256;
}
}
void Display_Pass(char pass[5])
{
for(int i = 0; i < 5; i++){
cout << pass[i] << " ";
}
}
void Cracked(char cracked[5], char pass[5])
{
do
{
for(int a = 0; a < 5; a++){
int b = rand()%256;
cracked[a] = char(b);
}
}while(cracked[0] != pass[0]);
do
{
for(int a = 0; a < 5; a++){
int b = rand()%256;
cracked[a] = char(b);
}
}while(cracked[1] != pass[1]);
do
{
for(int a = 0; a < 5; a++){
int b = rand()%256;
cracked[a] = char(b);
}
}while(cracked[2] != pass[2]);
do
{
for(int a = 0; a < 5; a++){
int b = rand()%256;
cracked[a] = char(b);
}
}while(cracked[3] != pass[3]);
do
{
for(int a = 0; a < 5; a++){
int b = rand()%256;
cracked[a] = char(b);
}
}while(cracked[4] != pass[4]);
}
void Display_Cracked(char cracked[5])
{
for(int i = 0; i < 5; i++){
cout <<  cracked[i] << " ";
}
}
int main()
{
char pass[5];
Generate_Pass(pass);
cout << "The Password is: ";
Display_Pass(pass);
cout << "n";
char cracked[5];
Cracked(cracked, pass);
cout << "The cracked password is: ";
Display_Cracked(cracked);
}

这就是我处理过的代码,但是每当我运行蛮力函数时,它都无法正常工作。

首先,在您的Cracked方法中,您只以一个索引为条件循环所有五个索引。你这样做了五次。平均需要 256 次尝试才能匹配正确的字符。这导致生成和分配大约 5*5*256=6400 个整数,这比您需要的工作量要多。

代码的问题在于,您要分配给每个do while循环中的所有五个索引。然后,您在上一个循环中找出的任何正确字符都将被下一个循环中的随机数据覆盖,以便只有最后一个字符是正确的。下面是解决这些问题的调整实现。

void Cracked(char cracked[5], char pass[5]) {
for (int a = 0; a < 5; a++) {
do {
int b = rand() % 256;
cracked[a] = char(b);
} while(cracked[a] != pass[a]);
}
}

由于for循环现在在外面,它将尝试随机的东西,直到它找出一个角色,然后移动到下一个角色而不接触任何其他角色。

您还会注意到,使用 for 循环会产生更少的代码,而代码大多相同。通常,如果您发现自己复制粘贴代码,这意味着您应该使用循环或函数或其他一些构造来避免额外的代码或让编译器为您生成代码。这使您的代码更易于维护。例如,如果要替换每个do while循环中使用的rand函数,则只需替换一次而不是五次。

此外,在这种情况下,最好单独尝试所有可能的值,而不是随机值(例如,使用for循环(。我会让你弄清楚那部分。

蛮力解决方案是:

系统地列举解决方案的所有可能候选者,并检查每个候选者是否满足问题的陈述

这意味着您需要生成给定长度的所有可能组合。(您永远无法保证已使用rand完成此操作。正如@Slava提到的,你不应该使用幻数,所以我们称之为长度:

#define LENGTH 5

从那里你可以做一个简单的嵌套while循环:

string Cracked(const char* pass) {
string result('', LENGTH);
while(!equal(cbegin(result), cend(result), pass)) {
if(result.back() < numeric_limits<unsigned char>::max()) {
++result.back();
} else {
for(auto it = rbegin(result); it != rend(result); *it++ = '') {
if(*it < numeric_limits<unsigned char>::max()) {
++(*it);
break;
}
}
}
}
return result;
}