我正在使用MATLAB中的一个项目,该项目旨在使用暴力破解用户输入的密码。我已成功将其设置为最多可以打破八个字符的密码,但我希望它能够处理任何长度的密码。就目前而言,代码基本上检查所有可能的一个字符密码,然后是所有可能的两个字符密码等。(注意:realpass是用户输入的密码,猜测是计算机生成的猜测,alphasize是字母表的长度我给MATLAB检查脚本的开头,即可能的字符数。)
% check all 1 character passwords possible w/ given alphabet
if strcmp(guess, realpass) == 0
for i = 1:alphasize(2)
guess(1) = alphabet(i);
if strcmp(guess, realpass) == 1
break
end
end
end
% the password has more than one characters, check all possible 2 character passwords
if strcmp(guess, realpass) == 0
for i = 1:alphasize(2)
guess(1) = alphabet(i);
for j = 1:alphasize(2)
guess(2) = alphabet(j);
if strcmp(guess, realpass) == 1
break
end
end
if strcmp(guess, realpass) == 1
break
end
end
end
正如你可能知道的那样,为了达到8个字符,有很多复制/粘贴,这是一个很好的指示,可以使用循环。我的麻烦是让循环行为正确。您可以在github上看到我的尝试。有没有人建议让这个东西运行起来?
非常感谢!
答案 0 :(得分:2)
解决方案是使用线性索引进行处理,并使用ind2sub
将其转换为字母表中的某个坐标。
代码比这里更长的解释更明确是我的蛮力解决方案:
function [testpass] = BruteForcePassword(realpass)
%[
if (nargin < 1), realpass = 'hello'; end
maxPassLength = 8;
alphabet = 'abcdefghijklmnopqrstuvwxyz';
for l = 1:maxPassLength,
% Number of possible password for this length
combinationCount = length(alphabet)^l;
% Put all possible combination in some sort of kilometer counter
% where each digit can run up to the number of elements in the alphabet
coordinate = cell(1,l);
size = length(alphabet) * ones(1,l);
for index = 1:combinationCount,
[coordinate{:}] = ind2sub(size, index); % transform linear index into coordinate
testpass = cellfun(@(i)alphabet(i), coordinate); % build password from current coordinate
% Test if password is ok
fprintf('Now testing: %s\n', testpass);
if (strcmp(testpass, realpass))
break;
end
end
if (strcmp(testpass, realpass))
break;
end
end
%]
end
一些解释
让我们首先考虑我们只有3个字符的字母表(只是因为它更简单,并没有失去一般性)。
当我们测试长度== 1的传球时,我们必须测试字母矢量中的所有3个位置。
1
2
3
当我们测试长度== 2的通过时,我们必须在第一个字符的字母表中修复一些位置,并为第二个字符测试所有3个位置。然后我们将第一个字符固定到字母表中的另一个位置,我们再次测试第二个字符的所有3个位置。最后我们再次确定第一个角色的位置,然后我们再次测试第二个位置的所有3个位置。
+----- Position in the alphabet for first character
|
| + -------- Position in the alphabet for second character
v v
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
因此,回到任何长度的字母表,就好像我们在大小为NxNxN...xN
的数组中运行所有位置,其中N
是字母表中的位置数。此数组的维数等于密码的长度。
在代码中我使用ind2sub
函数从线性索引位置重建数组坐标。
修改强>
由于组合的数量可以快速增长(N ^ l)并且可以超出系统编号表示以获得正确的线性索引...这里是更新代码的链接以运行所有坐标位置而根本不使用线性索引(即不使用ind2sub
):