验证密码的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个素数中找到。
发布于 2013-11-17 22:12:43
它只是将密码中匹配字符的数字相乘在一起,顺序并不重要,所以您所需要的只是计算数字。这是复杂的事实,val是一个32位的值,所以乘法可能溢出。在这种情况下,最简单的匹配密码会发生16527次。要解决这个难题,您需要使用64位整数来强制溢出的数量,并尝试对每个选项进行因式分解。只要尝试所有小写字符串也可以,密码只有9个字母。
发布于 2013-11-17 15:56:22
这段代码所做的是匹配密码,而不管密码的出现顺序如何。例如,如果我的密码是"BugsBunny“,它将接受"BBgnsuuy”。你可以得到这个,但不是原来的订单。
发布于 2013-11-18 12:22:27
该方法将始终返回false,因为变量"val“永远不会有值1066849907,因为2237和476911 (乘以这个值的素数)不在素数数组中。
因此,要么没有有效的密码,要么代码中有错误,并且应该有一个与1066849907不同的数字。
无论如何,这是一种非常无效和不安全的方法来验证密码。它忽略“密码”中的所有大写字母、所有数字和特殊字符,而不考虑字符在密码字符串中的位置。
例如,如果最后一个条件是
if (val == 30)然后下列所有密码都将作为有效密码通过:"abc“、"acb”、"bac“、"bca”、"cab“、"cba”、“123 123aSOMEcCHARSbHERE!$#”.
基本上,只要与"val“相比较的数字可以从素数数组中除以素数的乘积,就会有无限多的字符串作为有效的密码传递。
https://stackoverflow.com/questions/20032374
复制相似问题