遍历所有可能的字母组合

时间:2019-01-20 14:04:04

标签: c loops cs50 crypt

尝试使用蛮力破解密码,但是程序在找到密码时似乎没有意识到。

因此,我尝试编写一个小程序以使用蛮力破解密码。 基本上,我使用嵌套的for循环遍历所有字母组合(密码不得超过4个字母),然后使用给定盐(假定盐是固定的)对密码使用crypt来检查是否破解了密码(我可以访问加密的密码)。现在,我有了代码输出,它生成了什么,看起来好像在所有小写变体中进行了迭代。但是以某种方式它永远找不到密码。

现在我自己创建了加密版本,所以我知道密码的长度为4个字母,这不是问题,我认为程序似乎在所有可能的情况下都在进行迭代,那么可能是什么问题呢?如果条件错误?

现在我想这不是解决问题的最优雅的方法,但是我认为总体思路是正确的。但是,如果嵌套循环方法存在问题,我很乐意知道:)。

#define _XOPEN_SOURCE
 #include <unistd.h>

#include <stdio.h>
#include <string.h>
#include <cs50.h>
int main(int argc, string argv[]) {

if(argc < 2) {
printf("Please enter a password to crack! \n");
return 1;
}


char s[4] = "";



for(int i = 0; i <=27; i++) {

    if(i == 0)
    s[0] = 0;
    else
    s[0] =  i - 1 + 'a';

    if(strcmp(crypt(s, "50"), argv[1]) == 0) {

    break; }
        for(int j = 0; j <=26; j++) {
            if(j == 0)
            s[1] = 0;
            else
        s[1] = (j - 1 + 'a');

        if(strcmp(crypt(s, "50"), argv[1]) == 0)
        break;
            for(int k = 0; k <= 26; k++) {
                if(k == 0)
                s[2] = 0;

                s[2] =  (k - 1 + 'a');


            if(strcmp(crypt(s, "50"), argv[1]) == 0)
            break;
                for(int l = 0; l <= 26; l++) {
                    printf("%s \n", s);
                    if(l == 0)
                    s[3] = 0;
                    else
                    s[3] =  (l - 1 + 'a');



                    if(strcmp(crypt(s, "50"), argv[1]) == 0)
                    break;
                }

            }
        }


}

if (strcmp(crypt(s, "50"), argv[1]) != 0)
printf("Password not found");
else
printf("%s \n", s);

2 个答案:

答案 0 :(得分:0)

当数组具有四个非空字符时,声明char s[4]不能为空字符终止符留出空间,从而导致行为不是C标准所定义的。

答案 1 :(得分:0)

C字符串以null终止,这意味着C中的字符串基本上是一个字节/字符数组(类似于您初始化的字符串:char s[4] = "";),最后一个字节设置为0。

strcmp遍历两个字符串(字节数组),并逐一比较它们,直到找到不同的字符或两个字符串都结束为止,即当前比较的两个字节的字节均为0。当您将char数组s初始化为4个字节,并向其中写入4个非空字节时,strcmp将继续比较数组末尾的字节,因为它没有到达末尾。一个字符串。这也可能使程序崩溃或导致安全漏洞,因为您继续读入内存,这是不应该的。要解决此问题,请使用空字节正确终止输入字符串,并在可能的情况下使用strncmp函数,该函数带有一个附加参数,指示最多应比较多少个字符。

正如您正确识别的那样,嵌套循环方法并不是最优雅的解决方案,因为您要一遍又一遍地重复自己,结果代码非常严格,最多只能比较4个字符的密码。最好有一个外部for循环遍历所有可能的密码长度,然后调用一个函数,该功能检查一定长度的所有可能的密码(使用两个嵌套循环),这样更清洁。

如果您只是想暴力破解某些密码,而又不想自己编程,那么使用https://hashcat.net/hashcat/之类的专业工具可能会更好。