像这样初始化一个数组 pass2[2]="aa";不起作用

Initialize an array like this pass2[2]="aa"; does not work

我正在完成一项作业,其中我必须破解基于 DES 的散列密码。 用户在命令行参数中输入哈希密码;我散列每一种可能性(假设salt是50,pass是不超过4个字符并且字符可以是abc ... xyz 和 ABC...XYZ);当我的散列值和命令行中的散列值相等时,我打印未散列的密码。

使用 1 个字符长的密码一切正常,但我在使用 2 个字符长的密码时遇到了一些问题。 我希望这个问题很简短,不要让你不知所措,所以我会 post 我的整个代码放在最后,如果你想看的话

所以,我有这一行密码可能包含的字符:

string options="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

然后我建立可能的密码。 我从选项中取出第一个字符并将其存储在变量 pass2 的位置 [0](此时,pass2='a')。然后我对位置 [1] 执行与选项相同的次数(它存储 pass2 的第二个值 --> pass2='aa'..'aZ')。如果这些选项中的 none 是我要查找的密码,我将再次使用第一个字符 (pass2='bZ') 并尝试使用位置 [1] 的不同选项 ( pass2='ba')...等等。代码:

char pass2[0][1] = "aa";
for (int j=0, n=strlen(options); j<n; j++)
{
    pass2[0]=options[j];
    for (int i=0; i<n; i++)
    {
        pass2[1]=options[i];
        string hash2=crypt(pass2, "50");
        if (memcmp(hash2, argv[1], 13)==0)
        {
            printf("%s\n", pass2);
        }
    }
}

使用上面的代码,我希望我的程序获取变量 pass2 并存储以下内容:aa, ab, ac,..., aX, aY, aZ,..., Za, Zb、Zc、...、ZX、ZY、ZZ。当我阅读代码时,它对我来说很有意义。 (我零经验,但我真的觉得这次我写了一些连贯的应该有用的东西)。

然而,事实并非如此。这让我觉得我 wrote/declared/initialized 某些东西的方式可能存在一些问题。此外,以下错误代码支持该想法:

error: array initializer must be an initializer list
    char pass2[][1] = "ab";

如果有人知道问题出在哪里,请告诉我,因为我已经尝试了所有可能的方法来删除我在 answer 上找到的数组,但我仍然得到错误。好吧,即使我没有收到错误消息,它也不起作用,所以欢迎任何解决方案。

谢谢大家!

正如我之前所说,这是我的完整代码,以防有人想查看它:

#define _XOPEN_SOURCE
#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <crypt.h>

int main(int argc, string argv[])

{
    if (argc!=2){
        printf("Usage: ./crack hash\n");
        return 1;
    }

    string options="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char pass1[]="A";
    for (int i=0, n=strlen(options); i<n; i++)
    {
        pass1[0]=options[i];
        string hash1=crypt(pass1, "50");
        if (memcmp(hash1, argv[1], 13)==0)
        {
            printf("%c\n", options[i]);
            return 0;
        }
    }

    char pass2[0][1] = "aa";
    for (int j=0, n=strlen(options); j<n; j++)
    {
        pass2[0]=options[j];
        for (int i=0; i<n; i++)
        {
            pass2[1]=options[i];
        }

        string hash2=crypt(pass2, "50");
        if (memcmp(hash2, argv[1], 13)==0)
        {
            printf("%s\n", pass2);
        }
    }

}

一开始理解 C 数组的真正含义并不容易。问题是,方括号 [] 会在指针和数组之间造成各种混淆。

这里您需要的是一个能够容纳最大可能密码候选的数组。由于它被限制为 4 个字符,并且 C 字符串必须有终止字符 [=12=],因此您最多需要 5 个字节。

然后你将不得不用所有可能的组合来初始化这个候选字符串,如果是 1 到 4 个字母,这是一个经典的组合数学问题。

相当于以52进制(所有可能的字符)枚举所有n位数字,或者以52进制从0到52n-1,n介于1 和 4.

生成所有可能的密码候选的循环如下所示:

// despite the array notation, this is a pointer to a constant string of 53 chars
// (including the automatically generated terminating [=10=])
char Letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
#define ALPHABET_SIZE 52
#define MAX_PASSWORD_LENGTH 4

void try_password (long enumerator, int length)
{
    // this is an actual array that can hold 4 chars plus the [=10=] terminator
    char candidate[MAX_PASSWORD_LENGTH+1]; 
    int i;

    // convert the enumerator into a base 52 number
    // (will be written in reverse order, but in that case we don't care)
    for (i = 0 ; i != length ; i++)
    {
        candidate[i] = Letters[enumerator%ALPHABET_SIZE];
        enumerator /= ALPHABET_SIZE;
    }
    candidate[i] = '[=10=]'; // add string terminator

    // check password candidate
    if (check_password (candidate))
    {
        printf ("Yay! %s\n", candidate);
    }
}

void try_fixed_length_passwords (int length)
{
    long enumerator = 1; // must be big enough to hold 52^^4 - 1 (>= 24 bits)
    int i;
    for (i = 0 ; i != length ; i++) enumerator *= ALPHABET_SIZE;
    // now enumerator = 52^^length
    // you could also use math.h and compute enumerator = (long)pow(52,length)

    // enumerate all password candidates of a given length
    while (enumerator != 0)
    {
        enumerator--; /// will count from 52^^lenght-1 to 0
        try_password (enumerator, length);
    }
}

void try_all_passwords (void)
{
    // try all possible password lengths
    int i;
    for (i = 1 ; i <= MAX_PASSWORD_LENGTH ; i++) try_fixed_length_passwords(i);
}

所以,谢谢所有回答的人。 这是我解决它的方法。我以前写的地方:

char pass2[0][1] = "aa";
for (int j=0, n=strlen(options); j<n; j++)
{
    pass2[0]=options[j];
    for (int i=0; i<n; i++)
    {
        pass2[1]=options[i];
    }

    string hash2=crypt(pass2, "50");
    if (memcmp(hash2, argv[1], 13)==0)
    {
        printf("%s\n", pass2);
    }
}

再仔细看看

char pass2[0][1] =="aa";

我现在这样写:

char pass2[3] = "aa";

正如我在询问时所说,要声明变量数组(我仍在尝试找出它是哪一个),我正在按照我找到的指南进行操作 here;虽然显然我是在声明 array* 正确(在括号内指定长度),但我忘记了空终止符(kuroi neko 的回答让我想到了它)。这意味着,当我写 char pass2[2] = "aa" 但它不起作用时,我认为这是因为语法 - 或者 delcaring/initializing 它的方式 - 但实际上是我忘记了第三个字符“\0”,意思就是一直应该这样写:char pass2[3] = "aa".

这是...我的解决方案,char pass2[3] = "aa"。 如果您想查看完整代码,请看这里:再次感谢!

    #define _XOPEN_SOURCE
#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <crypt.h>

int main(int argc, string argv[])

{
    if (argc!=2){
        printf("Usage: ./crack hash\n");
        return 1;
    }

    string options="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char pass1[]="A";
    for (int i=0, n=strlen(options); i<n; i++)
    {
        pass1[0]=options[i];
        string hash1=crypt(pass1, "50");
        if (memcmp(hash1, argv[1], 13)==0)
        {
            printf("%c\n", options[i]);
            return 0;
        }
    }

    char pass2[3]= "aa";
    for (int i=0, n=strlen(options); i<n; i++)
    {
        pass2[0]=options[i];
        for (int j=0; j<n; j++)
        {
            pass2[1]=options[j];
            string hash2=crypt(pass2, "50");
            if (memcmp(hash2, argv[1], 13)==0)
            {
                printf("%s\n", pass2);
                return 0;
            }
        }


    }

    char pass3[4]= "aaa";
    for (int i=0, n=strlen(options); i<n; i++)
    {
        pass3[0]=options[i];
        for (int j=0; j<n; j++)
        {
            pass3[1]=options[j];
            for (int k=0; k<n; k++)
            {
                pass3[2]=options[k];
                string hash3=crypt(pass3, "50");
                if (memcmp(hash3, argv[1], 13)==0)
                {
                    printf("%s\n", pass3);
                    return 0;
                }
            }
        }
    }


    char pass4[5]= "aaaa";
    for (int i=0, n=strlen(options); i<n; i++)
    {
        pass4[0]=options[i];
        for (int j=0; j<n; j++)
        {
            pass4[1]=options[j];
            for (int k=0; k<n; k++)
            {
                pass4[2]=options[k];
                for (int l=0; l<n; l++)
                {
                    pass4[3]=options[l];
                    string hash4=crypt(pass4, "50");
                    if (memcmp(hash4, argv[1], 13)==0)
                    {
                        printf("%s\n", pass4);
                        return 0;
                    }
                }
            }
        }
    }
}