验证密码的C代码:
bool check(const char *password)
{
int val=1,pospassword=0,posletters;
int primes [] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101};
char letters []= "abcdefghijklmnopqrstuvwxyz";
do {
posletters=0;
do {
if (password[pospassword]==letteres[posletters])
val*=primes[posletters];
} while(++posletters<26);
} while (password[++pospassword]!='\0');
if (val==1066849907)
return true;
return false;
}
有没有办法从此代码中反向设计密码?
编辑:这个数字的因素是:2237和476911.这是问题,因为它们在前26个素数中找不到。
答案 0 :(得分:2)
它只是将密码中匹配字符的数字相乘,顺序无关紧要,所以您只需要考虑数字因素。由于val是32位值,因此乘法会溢出,这很复杂。在这种情况下,最简单的匹配密码会发生16527次。要解决这个难题,您需要使用64位整数来强制溢出次数并尝试分解每个选项。只需尝试所有小写字符串也可以,密码只有9个字母。
答案 1 :(得分:1)
此代码似乎与密码匹配,无论其出现的顺序如何。 例如,如果我的密码是“BugsBunny”,它将接受“BBgnsuuy”。 您可以获得此订单,但不能获得原始订单。
答案 2 :(得分:0)
该方法将始终返回false,因为变量“val”将永远不会具有值1066849907,因为2237和476911(相乘的素数给出此值)不在primes数组中。
所以要么没有有效的密码要么代码中有错误,应该有一个不同于1066849907的数字。
无论如何,验证密码的方式非常无效且不安全。它忽略了“密码”中的所有大写字母,所有数字和特殊字符,并没有考虑字符在密码字符串中的位置。
例如,如果最后一个条件是
if (val == 30)
然后以下所有内容都将作为有效密码传递:“abc”,“acb”,“bac”,“bca”,“cab”,“cba”,“123aSOMEcCHARSbHERE!$#”...
基本上只要与“val”进行比较的数字可以除以素数数组中素数的乘积,就会有无数个字符串作为有效密码传递。