C 为了解决密码问题,代码需要运行很长时间,需要对其进行优化

C 为了解决密码问题,代码需要运行很长时间,需要对其进行优化,c,linux,cryptography,time-complexity,cs50,C,Linux,Cryptography,Time Complexity,Cs50,我正在构建一个程序,其中一个人将使用linux命令行发出密码的散列作为第二个参数(./program,运行该程序,作为第一个参数),程序将为他找到具有相应散列(aka password)的字符串。密钥需要最多4个字符长(a-z,a-z),并带有2位salt(a-z,a-z,0-9)。作为一个完全的初学者,除了使用6个循环来计算所有可能的组合之外,我想不出别的方法,这肯定需要程序几个小时来解决。这个问题是在线课程习题集(哈佛cs50)的一部分,我正在使用课程的库,因此如果您希望能够使用下面程序中的

我正在构建一个程序,其中一个人将使用linux命令行发出密码的散列作为第二个参数(./program,运行该程序,作为第一个参数),程序将为他找到具有相应散列(aka password)的字符串。密钥需要最多4个字符长(a-z,a-z),并带有2位salt(a-z,a-z,0-9)。作为一个完全的初学者,除了使用6个循环来计算所有可能的组合之外,我想不出别的方法,这肯定需要程序几个小时来解决。这个问题是在线课程习题集(哈佛cs50)的一部分,我正在使用课程的库,因此如果您希望能够使用下面程序中的函数和数据类型,以免被迫提出您使用的库的相应函数/类型,您可以在edx上创建一个帐户并输入cs50.io。以下是问题的描述,如果您需要更多信息:

源代码:

#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, string argv [])
{
    if (argc != 2){
        printf ("Oops! Goodbye!\n");
        return 1;
    }

    char letters [] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',     'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                        'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E',    'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    char leet [] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                    'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    char key [4];
    char salt [2];
    int i, j, k, l, m, n;
    for (i = 0; i < 52; i++){
        for (j = 0; j < 52; j++){
            for (k = 0; k < 52; k++){
                for (l = 0; l < 52; l++){
                    for (m=0; m < 62; m++){
                        for (n=0; n < 62; n++){
                        key [0] = letters [i];
                        key [1] = letters [j];
                        key [2] = letters [k];
                        key [3] = letters [l];
                        salt [0] = leet [m];
                        salt [1] = leet [n];
                        if (strcmp(crypt (key, salt), argv [1])==0){
                            printf ("%c%c%c%c", key [0], key [1], key [2], key [3]);
                            break;
                       }   
                   }   

                }

            }
        }
    }
}
printf ("\n");
return 0;
}
定义源代码
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符串argv[])
{
如果(argc!=2){
printf(“噢!再见!\n”);
返回1;
}
字符字母[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
“v”,“w”,“x”,“y”,“z”,“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,“L”,“M”,“N”,“O”,“P”,
‘Q’、‘R’、‘S’、‘T’、‘U’、‘V’、‘W’、‘X’、‘Y’、‘Z’};
字符长度[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u',
“v”,“w”,“x”,“y”,“z”,“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,“L”,“M”,“N”,“O”,“P”,
‘Q’、‘R’、‘S’、‘T’、‘U’、‘V’、‘W’、‘X’、‘Y’、‘Z’、‘0’、‘1’、‘2’、‘3’、‘4’、‘5’、‘6’、‘7’、‘8’、‘9’;
字符键[4];
焦盐[2];
int i,j,k,l,m,n;
对于(i=0;i<52;i++){
对于(j=0;j<52;j++){
对于(k=0;k<52;k++){
对于(l=0;l<52;l++){
对于(m=0;m<62;m++){
对于(n=0;n<62;n++){
键[0]=字母[i];
键[1]=字母[j];
键[2]=字母[k];
键[3]=字母[l];
盐[0]=leet[m];
盐[1]=leet[n];
if(strcmp(crypt(key,salt),argv[1])==0){
printf(“%c%c%c%c”,键[0],键[1],键[2],键[3]);
打破
}   
}   
}
}
}
}
}
printf(“\n”);
返回0;
}
除了复杂性之外,如果你发现还有什么可以改进或应该改变的,请告诉我。我们将非常感谢您的建议

编辑:谢谢你花时间回答。我已经考虑了您的所有建议并更改了代码,但由于某种原因它仍然不会运行(它不会打印任何内容,就好像条件(strcmp函数)永远不会满足一样)。你能详细说明问题出在哪里吗?还有一个问题。如何在接受命令行参数的程序中使用调试器?每当我使用调试器运行程序时,默认情况下它只接受“/program”参数并退出。以下是新代码的外观:

#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, string argv [])
{
    char salt [] = "50";
    if (argc != 2)
    {
        printf ("Oops! Goodbye!\n");
        return 1;
    }

    char letters [] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char key [4];
    int i, j, k, l;
    for (i = 0; i < 52; i++){
        for (j = 0; j < 53; j++){
            for (k = 0; k < 53; k++){
                for (l = 0; l < 53; l++){
                        key [0] = letters [i];
                        key [1] = letters [j];
                        key [2] = letters [k];
                        key [3] = letters [l];
                        if (strcmp(crypt (key, salt), argv [1])==0)
                        {
                            printf ("%c%c%c%c", key [0], key [1], key [2], key [3]);    
                            break;
                        }

                }
            }
        }
    }
    printf ("\n");
    return 0;
}
定义源代码
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符串argv[])
{
焦盐[]=“50”;
如果(argc!=2)
{
printf(“噢!再见!\n”);
返回1;
}
字符字母[]=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz”;
字符键[4];
int i,j,k,l;
对于(i=0;i<52;i++){
对于(j=0;j<53;j++){
对于(k=0;k<53;k++){
对于(l=0;l<53;l++){
键[0]=字母[i];
键[1]=字母[j];
键[2]=字母[k];
键[3]=字母[l];
if(strcmp(crypt(key,salt),argv[1])==0)
{
printf(“%c%c%c%c”,键[0],键[1],键[2],键[3]);
打破
}
}
}
}
}
printf(“\n”);
返回0;
}

问题陈述:

一定要仔细阅读crypt,特别注意它提到的“盐”:

人穴

是你干的吗?然后你会注意到盐是作为散列的前两个字符提供给你的。 等一下,看看那些散列密码:他们真的对每个密码都使用相同的密码吗??那是糟糕的安全措施。(提示:您正在学习一门名为CS50的课程,每个密码上的salt为50)


做杂烩时,盐的作用是什么?它阻止攻击者做什么?这些问题的答案将告诉您如何提高性能。祝你好运。

问题陈述:

一定要仔细阅读crypt,特别注意它提到的“盐”:

人穴

是你干的吗?然后你会注意到盐是作为散列的前两个字符提供给你的。 等一下,看看那些散列密码:他们真的对每个密码都使用相同的密码吗??那是糟糕的安全措施。(提示:您正在学习一门名为CS50的课程,每个密码上的salt为50)


做杂烩时,盐的作用是什么?它阻止攻击者做什么?这些问题的答案将告诉您如何提高性能。祝你好运。

有两件事:首先,正如有人所说,你必须将以NULL结尾的字符串传递给crypt。你通过的是