C 检查每一个报价(&Q);字;从aaa..a到zzz..z

C 检查每一个报价(&Q);字;从aaa..a到zzz..z,c,multithreading,loops,crypt,C,Multithreading,Loops,Crypt,我的程序应该是一个蛮力密码破解程序(学校作业)。 输入参数如下所示 ./crack threads keysize target 程序需要检查长度为keysize的密码,但也需要检查较短的密码。 我不确定如何着手写一些一次只改变一个字母的东西,然后继续写下去。。 (最大键大小将变为8) 例如 keysize=5,因此循环(我认为)需要将等于“aaaaa”的内容修改为“aaaab”或“aaaac”,将每个结果与salt(目标的前两个字符)一起放入crypt_r(),直到找到匹配项 我使用cryp

我的程序应该是一个蛮力密码破解程序(学校作业)。 输入参数如下所示

./crack threads keysize target
程序需要检查长度为keysize的密码,但也需要检查较短的密码。 我不确定如何着手写一些一次只改变一个字母的东西,然后继续写下去。。 (最大键大小将变为8)

例如

keysize=5,因此循环(我认为)需要将等于“aaaaa”的内容修改为“aaaab”或“aaaac”,将每个结果与salt(目标的前两个字符)一起放入crypt_r(),直到找到匹配项

我使用crypt\u r是因为下一步是添加多线程


不确定是否还需要其他东西来解释这个问题。很高兴澄清。

此代码将在所有密码中循环,循环长度不超过给定长度,并且只包含从
a
z
的字母:

#include <stdio.h>
int main(void) {
    char password[9] = {0};
    int keysize = 5;
    for (;;) {
        // get next password value
        // we do it by adding 1 in 26-al system
        int level = 0; // current level, starts at 0
        while (level < keysize) {
            if (password[level] == 0) {
                password[level] = 'a';
                break;
            }
            if (password[level] >= 'a' && password[level] < 'z') {
                password[level]++;
                break;
            }
            if (password[level] == 'z') {
                password[level] = 'a';
                level++;
            }
        }
        if (level >= keysize)
            break; // we have checked all passwords!
        // check if password matches:
        //printf("Checking password: '%s'\n", password);
        if (check_password(password)) {
            printf("Hooray! Password found: %s\n", password);
            break;
        }
    }
    return 0;
}
#包括
内部主(空){
字符密码[9]={0};
int-keysize=5;
对于(;;){
//获取下一个密码值
//我们通过在26 al系统中添加1来实现
int level=0;//当前级别从0开始
while(级别='a'&密码[级别]<'z'){
密码[级别]+;
打破
}
如果(密码[级别]==“z”){
密码[级别]=“a”;
级别++;
}
}
如果(级别>=按键大小)
break;//我们已经检查了所有密码!
//检查密码是否匹配:
//printf(“正在检查密码:“%s”\n”,密码);
如果(检查密码(密码)){
printf(“万岁!找到密码:%s\n”,密码);
打破
}
}
返回0;
}
如果您将a标签限制为
a
b
c
,并将keysize设置为4,它将检查以下密码:

abb abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc aba baa baa baa baa baa baa baa baa baa baa baa baa bab aba bab aba bab bab bac abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网中国英语学习网


请参见

上的示例,让我们看看。有10^n个可能的n位十进制数。因此,有26^8个可能的8字符密码只使用字母a-z。总共是208827064576

您可以使用简单的64位计数器跟踪数字,然后将数字转换为base-26表示形式。比如:

long max = 208827064576;
longlong counter = 0;

while (counter < max)
{
    char password[9];
    GetPassword(counter, password);
    // do whatever you want with the password
    ++counter;
}

void GetPassword(longlong count, char* pass)
{
    int i;
    int rem;
    if (count == 0)
    {
        pass[0] = 'a';
        pass[1] = '\0';
        return;
    }
    i = 0;
    do
    {
        int rem = count % 26;
        pass[i] = 'a' + rem;
        ++i;
        count /= 26;
    } while (count > 0)
}
long max=208827064576;
隆隆计数器=0;
while(计数器<最大值)
{
字符密码[9];
GetPassword(计数器、密码);
//你想用密码做什么就做什么
++计数器;
}
void GetPassword(longlong计数,char*pass)
{
int i;
内部rem;
如果(计数=0)
{
通过[0]=“a”;
通过[1]='\0';
返回;
}
i=0;
做
{
int rem=计数%26;
通过[i]=“a”+rem;
++一,;
计数/=26;
}而(计数>0)
}
通过使用
计数器
变量的互锁增量,您可以轻松地使多个线程都可以使用该变量。或者您可以分割搜索空间,使一个线程从0开始,一个线程从26^7开始(这将是baaaaaa),等等


2000亿是一个相当大的数字。十亿秒等于32年。即使你每秒可以检查几千个(不太可能),也需要花费相当长的时间来进行彻底的搜索。

我们如何验证这是一项学校作业?如果你真的只是在“aaaa…a”到“zzzz…z”之间行进,那么你可以将其视为一个以26为基数的数字,并在循环中“递增”它。如果您可以允许字符串长度小于最大长度,则以“a”(将顶部位置视为空)开始,并允许在溢出
z+1
@enginefree时滚动到空位置。如果不是学校作业,则在中已经存在一个远优于此的实现。@paddy:递归不是万灵药。实际上,我根本不会使用它。你可以将密钥表示为长(64位)整数,并将其视为基数为26的数字。所以0变成了“aaaaaa”,等等。然后您所需要的就是将longint转换为其base-26表示形式,这可能是您已经知道如何做的事情。(想想如果没有
printf
itoa
等,您将如何输出十进制或十六进制的整数)谢谢。看起来真不错。我会试试看这是怎么回事。如果你不介意我问的话。。“for(;)”是做什么的?以前没有见过(;)的
相同,而(true)
-在给定的两件事情中,你的似乎是最好的。我现在只是在让我的程序验证哪个密码是正确的时候遇到了麻烦。如果你认为你能帮上忙的话,我给你提出了另一个问题。谢谢,吉姆。我认为本作业的真正目的是学习如何实现多线程。我们应该允许程序使用最多8个线程。有人建议我们要么将每个线程的可能选择范围分割开来进行搜索,要么使用“共享当前密码进行尝试”,并使用锁进行搜索。您的
do{}
必须是一个循环才能有意义,但它不是,因此它将不起作用。尝试实现此代码后(我不得不在
do{}
中添加一个while条件,我得到了一个seg