【问题标题】:Iterating through all possible Letter combinations遍历所有可能的字母组合
【发布时间】:2019-01-20 14:04:04
【问题描述】:

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

所以我尝试编写一个小程序来使用暴力破解密码。 基本上我使用嵌套的 for 循环遍历所有字母组合(密码不必超过 4 个字母),然后我在密码上使用给定盐的 crypt(假设盐是固定的)来检查我是否破解了密码(我可以访问加密的密码)。现在我有代码输出它生成的内容,看起来它确实遍历了所有小写变体。但不知何故,它永远找不到密码。

现在我自己创建了加密版本,所以我知道密码是 4 个字母长,这不是问题,我认为程序确实似乎遍历了所有可能性,那么问题可能是什么? if条件错了吗?

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

#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);

【问题讨论】:

    标签: c loops cs50 crypt


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      正如您正确识别的那样,嵌套循环方法并不是最优雅的解决方案,因为您一遍又一遍地重复自己,并且生成的代码非常死板,最多只能比较 4 个字符的密码。如果有一个外部 for 循环来遍历可能的密码长度,然后调用一个函数来检查所有可能的一定长度的密码(使用两个嵌套循环),那会更干净。

      如果您只是想对某些密码进行暴力破解,而不是真的想自己编程,您可能会更好地使用像https://hashcat.net/hashcat/ 这样的专业工具。

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 1970-01-01
        • 2022-11-29
        • 2014-07-14
        • 1970-01-01
        • 2013-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多