像这样初始化一个数组 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;
}
}
}
}
}
}
我正在完成一项作业,其中我必须破解基于 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;
}
}
}
}
}
}