我已经在代码开头解释了我的程序如何工作。请查看其中的一些屏幕截图,以便于理解。
我的程序确实运行良好,但是有点脏,如果我解决了这两个问题,它可能会更快:
主代码没有那么长。它看起来又长又脏,因为我在switch case语句中复制了8次代码块。例如,情况1循环一个字符长度的密码。
case 2
=两个字符,case 8
= 8个字符长度的密码。这些情况之间唯一的区别是“ for循环”计数。 case 1
有1个for
循环,case 8
有8个嵌套的for循环。我想使我的代码更漂亮,那么如何摆脱此复制/粘贴的代码并将其变成当前大小的1/8? Ctrl +鼠标滚轮向下,缩小并查看复制的粘贴部分。先尝试1位数,然后尝试2位数,再尝试3位数,依此类推。因此,它应该等待1、2、3来获得4位数字。而且这会使程序在高位数时浪费很多时间。我的CPU是i7 3770k,有6个内核,程序只能运行一个。我猜是因为它说CPU使用率为13%。我想提高它,例如在同一任务上使用6个核心,否则每个核心将只承担一部分。第一个内核将仅循环循环8个字符长度的字符,第二个内核将对7个字符长度的字符进行相同的操作……当其中一个找到答案时,程序将结束。我们真的可以做到吗?
这是代码
#include <iostream>
#include <ctime>
using namespace std;
string crackPassword(string pass);
long long int attempt;
clock_t start_t, end_t;
int main(){
string password;
cout << "Enter the password to crack : ";
cin >> password;
cout << endl << endl << endl << ">\n>> CRACKED THE PASSWORD! >>\n>" << endl << endl <<"The password : " << crackPassword(password) << endl;
cout << "The number of attempts : " << attempt << endl;
cout << "The time duration passed : " << (double)(end_t - start_t)/1000 << " seconds" << endl << endl;
return 0;
}
string crackPassword(string pass){
int digit[7],alphabetSet=1,passwordLength=1;
start_t = clock();
string test,alphabet = "1337 also daktari is pro";
while(1){
switch(passwordLength){
case 1:
while(alphabetSet<4){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
}
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 2:
alphabetSet=1;
while(alphabetSet<6){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 3:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 4:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[3]=0;digit[3]<alphabet.length();digit[3]++)
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 5:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[4]=0;digit[4]<alphabet.length();digit[4]++)
for(digit[3]=0;digit[3]<alphabet.length();digit[3]++)
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 6:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[5]=0;digit[5]<alphabet.length();digit[5]++)
for(digit[4]=0;digit[4]<alphabet.length();digit[4]++)
for(digit[3]=0;digit[3]<alphabet.length();digit[3]++)
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 7:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[6]=0;digit[6]<alphabet.length();digit[6]++)
for(digit[5]=0;digit[5]<alphabet.length();digit[5]++)
for(digit[4]=0;digit[4]<alphabet.length();digit[4]++)
for(digit[3]=0;digit[3]<alphabet.length();digit[3]++)
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
case 8:
alphabetSet=1;
while(alphabetSet<8){
switch(alphabetSet){
case 1 : alphabet = "-0123456789";
cout << endl << endl <<"Testing only digits(0123456789) - 10 Characters, please wait"; break;
case 2 : alphabet = "-abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only lowercase characters(abcdefghijklmnopqrstuvwxyz) - 26 Characters, please wait"; break;
case 3 : alphabet = "-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing only uppercase characters(ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 26 Characters, please wait"; break;
case 4 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyz";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyz) - 36 Characters, please wait"; break;
case 5 : alphabet = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing uppercase characters and numbers(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ) - 36 Characters, please wait"; break;
case 6 : alphabet = "-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 52 Characters, please wait"; break;
case 7 : alphabet = "-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << endl << endl << "Couldn't find the password, increasing the searching level."<< endl << endl << "Testing lowercase, uppercase characters and numbers(0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ) - 62 Characters, please wait"; break;
}
for(digit[7]=0;digit[7]<alphabet.length();digit[7]++)
for(digit[6]=0;digit[6]<alphabet.length();digit[6]++)
for(digit[5]=0;digit[5]<alphabet.length();digit[5]++)
for(digit[4]=0;digit[4]<alphabet.length();digit[4]++)
for(digit[3]=0;digit[3]<alphabet.length();digit[3]++)
for(digit[2]=0;digit[2]<alphabet.length();digit[2]++)
for(digit[1]=0;digit[1]<alphabet.length();digit[1]++)
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
attempt++;
if(attempt%2500000==0) cout << ".";
test=alphabet[digit[0]];
for(int i=1;i<passwordLength;i++)
if(alphabet[digit[i]]!='-')test+=alphabet[digit[i]];
if(pass.compare(test)==0){end_t = clock(); return test;}
}
alphabetSet++;
}
break;
}
cout << endl << endl << endl << endl << "*" << endl;
cout << "*** Password length is not " << passwordLength << ". Increasing password length! ***";
cout << endl << "*" << endl << endl;
passwordLength++;
}
}
#1 楼
不要养成使用
using namespace std
的习惯。请确保包括
<string>
。对于
<ctime>
库,应使用std::clock_t
而不是clock_t
。最好避免使用全局变量:
long long int attempt;
clock_t start_t, end_t;
由于可以在程序中的任何位置修改这些变量,因此可能会引入错误,这也会损害可维护性和可测试性。 >
您应该在
attempt
中将main()
初始化为0(正在递增),然后通过引用将其传递给crackPassword()
。这样,您将知道只有这两个功能才能识别attempt
(如果您添加了其他功能)。start_t
和end_t
只需位于main()
中。我还建议重命名它们(特别是删除_t
),否则可能看起来它们是库的一部分。无需使用
std::endl
如此多次,还刷新缓冲区,不必要地减慢了代码速度。只需使用"\n"
,它仅提供换行符。它还可以使代码短一些,尤其是在可以将其放入现有的硬编码输出行的地方。例如,
cout << endl << endl << endl << ">\n>> CRACKED THE PASSWORD! >>\n>" << endl << endl <<"The password : " << crackPassword(password) << endl;
将变成这样:
cout << "\n\n\n>\n>> CRACKED THE PASSWORD! >>\n>\n\n The password : " << crackPassword(password) << "\n";
为了清晰起见,您也可以将其分成单独的行,并保持较短的行:
cout << "\n\n\n>\n>> CRACKED THE PASSWORD! >>\n>\n\n;
cout << "The password : " << crackPassword(password) << "\n";
这里不需要特别的C样式转换:
(double)(end_t - start_t)/1000
发布Q4312079q的C ++方式:
static_cast<double>(end_t - start_t)/1000
此外,如果需要在其他地方使用它,请考虑将其作为变量使用。您还应该使用库中的
static_cast<>
宏。double timeDuration = static_cast<double>(end_t - start_t) / CLOCKS_PER_SEC;
在
CLOCKS_PER_SEC
中,应将crackPassword()
传递给pass
而不是按值传递它没有在函数内部被修改。这也会保存不必要的副本。string crackPassword(string const& pass){
最好每行有一个变量声明/初始化:
int digit[7];
int alphabetSet=1;
int passwordLength=1;
这将使每个变量都更加可见。如果需要,也可以为单独的变量添加注释。
这样的行:
for(digit[0]=1;digit[0]<alphabet.length();digit[0]++){
应使用适当的空格以提高可读性:
for (digit[0] = 1; digit[0] < alphabet.length(); digit[0]++) {
通常,请保留运算符之间的空格,对于
const&
循环语句,也应将各部分也分开。如果由于行太长而避免了这种情况,则应该以其他方式有效地缩短它。所有这些都将有助于提高可读性。
评论
\ $ \ begingroup \ $
您能解释一下为什么“使用命名空间标准”不好吗?谢谢您,这些信息对我有用!
\ $ \ endgroup \ $
–user38928
2014年3月18日在6:30
\ $ \ begingroup \ $
@daktari:通常不建议这样做,因为它会将STL代码(包含在std名称空间中)公开给全局名称空间。例如,如果您要创建自己的字符串类并使用某些相同的名称,则使用命名空间std时,将发生名称冲突。这会造成歧义,并可能阻止编译。对于小型应用程序,或者将其放在本地范围内(例如函数),则没什么大不了的。但是,如果将其放到全局中,则它会暴露给整个程序。
\ $ \ endgroup \ $
– Jamal♦
2014年3月18日在6:36
#2 楼
@ChrisW提出了一个很好的观点,但并没有完全理解我的想法。他是完全正确的,您所做的基本上只是在数数。他没有指出的是,它可以(并且应该应该)实现为实际计数。
例如,要测试所有最长8个字符的密码,仅使用字母数字,我们最终只是简单地从0到99999999进行计数。我们将每个数字从一个数字转换为一个字符串,然后测试结果字符串。
但是,我建议您建议不要使用测试1的策略一个线程中的位数,第二个线程中的2位,依此类推。问题很简单:您添加的每个数字将组合数乘以10。您的第一个线程测试1位密码,只有10种可能性。到最后一个线程(8位密码)时,它的可能性是第一个线程的108倍。显然,第一个比最后一个要快得多。大多数时间仍将仅由一个线程(仅在一个内核上运行)消耗。
相反,您想将整个范围划分为一组大小相等的子范围。给定100000000个组合,您希望在每个核上测试大约100000000/8 = 12500000个可能性。为此,您有一个线程测试可能性,范围是0到12500000,下一个线程测试可能性是12500000到25000000,依此类推,直到达到99999999。这样,每个线程的工作量大致相等,因此所有内核均分担工作。
有两种不同的方法可以做到这一点。一种是显式创建线程,每个数字范围一个。另一种可能性是将大多数代码保留为一个相当简单的循环,并使用OpenMP将循环拆分为多个线程:
#pragma omp parallel for
for (long long i = 0; i<9999999ULL; i++) {
std::string candidate = std::to_string(i);
if (test_password(candidate))
std::cout<<"We found it!\n"<<candidate<<"\n";
}
在我的笔记本电脑上进行快速测试,这将密码的搜索时间从大约3秒减少到不到1秒。当然,绝对速度取决于测试密码所需的时间,但是只要您可以从多个线程同时测试密码(或者测试密码比生成一个密码要快得多),您就可以从多线程中获得可观的速度。
如果您想做大致相同的事情,但是(例如)将字母和数字混合在一起,则仍然可以使用相同的基本思想。唯一的区别是将数字转换为字符串的基础。例如,要仅使用字母(而不是数字),可以执行以下操作:
std::string to_string(long long val) {
std::string ret;
while (val) {
ret += ('a' + val % 26);
val /= 26;
}
}
要创建数字和字母的混合体,通常最简单的方法是一个要使用的字符数组,然后索引到该数组:
char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
std::string to_string(long long val) {
std::string ret;
static const size_t size = sizeof(digits) -1;
while (val) {
ret += digits[val % size];
val /= size;
}
}
在某些时候,这将不再正常工作,仅仅是因为很长的时间long(甚至
unsigned long long
)足够大,可以产生给定范围内的所有数字。如果您需要/想要搜索较大范围的内容,则可能需要做其他事情来改善搜索范围。 unsigned long long
的范围至少为64位,生成所有64位数字所花的时间将比您可能等待的时间长(即使我们忽略转换并测试结果,仅从0到0xffffffffffffffff进行计数也将比大多数人愿意等待。评论
\ $ \ begingroup \ $
这是修复程序,如果有人对to_string和
\ $ \ endgroup \ $
–user38928
2014年3月18日在10:05
\ $ \ begingroup \ $
我只尝试了两个字母以及“数字和字母的混合”,它们都从1循环到999999,我看不到任何字母。 std :: string to_string(long long val); int main(){std :: string密码; std :: cin >>密码;对于(long long i = 0; i <9999999ULL; i ++){std :: string候选= std :: to_string(i);如果(password.compare(candidate))std :: cout <<“ \ n” << candidate <<“ \ n”; std :: string to_string(long long val){std :: string ret;而(val){ret + =('a'+ val%26); val / = 26; }}
\ $ \ endgroup \ $
–user38928
2014年3月18日在16:44
\ $ \ begingroup \ $
@daktari这是一个小写字母的字母:('a'+ val%26);因为val%26是一个数字;当val%26为0时,字母为'a'+ 0,即'a';当val%26为1时,字母为'a'+ 1为'b';替代地,这是字典中一个名为“ digits”的字母:digits [val%size]
\ $ \ endgroup \ $
– ChristW
2014年3月18日在16:53
\ $ \ begingroup \ $
是的,但是正如我所说,当我打印数字时,它只会循环显示数字,即使它使a,b,c都将它们加在一起,例如:zz然后是aaa,然后是aab,然后是aac等。
\ $ \ endgroup \ $
–user38928
2014年3月18日在21:16
#3 楼
这两种情况之间唯一的区别是“ for循环”计数,情况1的循环为1,情况8的循环为8。我想让我的代码更漂亮,因此如何摆脱此复制粘贴代码并使之成为当前大小的1/8。
遍历密码就像计数数字:
从第一个数字“ 0”开始递增,直到达到最后一个数字“ 9”
下一个递增,递增下一个数字并重置该数字“ 10“
再次增加第一个数字:” 11“,” 12“,等等。
必须增加下一个数字:” 20“
如果不能增加下一个数字数字然后增加一个数字:“ 99”“ 100”
类似(未测试的代码):
// try up to 8 digit password
char password[9];
// password is null terminated
password[8] = 0;
// password is initially zero-filled
memset(password,0,8);
// start at last character and make it bigger by building to the left
char* pass = &password[7];
for (;;)
{
for(int i = 0; i < alphabet.length; ++i)
{
password[7] = alphabet[i];
// test for password match here
if (test.compare(pass))
return string(pass); // found!
}
// increment one or more chars to the left
// and maybe decrement pass to make it bigger
// before we run the above for loop again on the right-most char
for (int j = 6; j >= 0; --j)
{
if (password[j] == 0)
{
// first time we've overflowed this high
--pass;
password[j] = alphabet[0];
break;
}
// increment the existing character
string::size_t found = alphabet.find(password[j]);
++found;
if (found < alphabet.length)
{
password[j] = alphabet[found];
break;
}
// else need to overflow to the next higher
password[j] = alphabet[0];
if (j == 0)
{
// can't go higher, return failure
return string("");
}
continue; // i.e. try again with --j
}
}
评论
\ $ \ begingroup \ $
我将对其进行测试,它看起来确实不错,但是将“递归”用于“嵌套循环”又如何呢?
\ $ \ endgroup \ $
–user38928
2014年3月18日在6:35
\ $ \ begingroup \ $
在我看来,递归似乎是另一种可能的有效实现方式。
\ $ \ endgroup \ $
– ChristW
2014年3月18日在16:32
\ $ \ begingroup \ $
我无法将嵌套循环转换为某些递归函数,这太复杂了。
\ $ \ endgroup \ $
–user38928
2014年3月18日在16:46
评论
“我想像6核一样提高它……我们真的可以做到吗?”是的,那可以做到。为此,我认为您需要使用“多线程”。 C ++ 11内置了对多线程的支持(请参见此处的示例)。