Простой алгоритм взломать 4-х значный пароль в Delphi
Я просто не могу разобраться с алгоритмом, который, как я изначально думал, будет относительно простым.
По сути, пользователь вводит комбинацию из 4 длинных чисел (0 - 9), и мне нужен алгоритм, который будет пробовать каждую возможную комбинацию, пока она не совпадет с той, что была введена пользователем.
Как я уже сказал, это, вероятно, довольно просто с вложенными циклами или чем-то еще, но я просто не могу разобраться с этим.
Ценю любую помощь. Кстати, я использую Delphi.
4 ответа
Появляется вопрос, как задать все 4-значные строки, используя цифры '0'
в '9'
,
Вы можете сделать это легко с for
цикл и вызов Format
:
for i := 0 to 9999 do
str := Format('%.4d', [i]);
Спецификатор точности в строке формата гарантирует, что строка будет дополнена нулями.
for i := 1 to 9999 do
TryCombo(i);
Нет необходимости делать вложенные циклы. Если они вам нужны в символьной форме, проще использовать IntToStr, чем просто использовать комбинации и вложенные циклы. Если он должен быть дополнен, используйте простой цикл:
s:= inttostr(i);
while length(s) < 4 do
s := '0' + s;
Хотя ответ @Simpson Bart является самым быстрым решением вашей конкретной проблемы, у меня есть ощущение, что вы, возможно, являетесь студентом факультета компьютерных наук, и вам дали эту задачу в качестве домашней работы.
Если это так, я полагаю, что ваш учитель / профессор, вероятно, захочет, чтобы вы внедрили собственный счетчик, с помощью которого вы будете тестировать все возможные комбинации, пока не найдете основную.
В случае нахождения паролей таким способом это называется грубой атакой.
Так как ты это делаешь?
Сначала подумайте о математике и использовании различных систем счисления. Зачем? Поскольку для реализации пользовательского счетчика вам необходимо создать собственную систему счисления. А базовый номер вашей системы счисления - это количество возможных символов, которые можно использовать в пароле. В вашем случае это 10 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9).
Второе, что вам нужно сделать, это создать строку, содержащую все возможные символы. Мы используем это позже для чтения определенных символов, находя их по индексу, который является позицией в строке.
Затем вы просто подсчитываете в своей новой системе счисления и генерируете возможный пароль, назначая конкретные символы из строк, содержащих все возможные символы. Вы делаете это, читая определенный символ, положение которого определяется значением конкретной цифры в вашей системе счисления.
И, наконец, вы проверяете, совпадает ли сгенерированный пароль с тем, который вы ищете.
Я надеюсь, что мое объяснение того, как вы должны подходить к этой проблеме, достаточно понятно, так как я не являюсь носителем английского языка, поэтому возможно, что я не выразил себя наилучшим образом.
Если нет, я также публикую пример кода ниже с комментариями, которые могут быть более понятными.
const
//String containing all possible lower case leters and numbers of english alphabet
CPossibleLowercaseLetersNumbersChars: AnsiString = '0123456789abcdefghijklmnopqrstuvwxz';
//String containing all possible chars used in HexDecimal numeral system
CPossibleHexChars: AnsiString = '0123456789abcdef';
implementation
function BruteForcePasswordFinder(InputStr: AnsiString; PossibleChars: AnsiString): AnsiString;
var Num1, Num2, Num3, Num4: Integer; //Could use Byte (integer from 0 to 255) instead
//String for temporary storing password string we generate
TempPassString: AnsiString;
begin
//Set initial conditions
Num1 := 0;
Num2 := 0;
Num3 := 0;
Num4 := 0;
Result := '';
//Check to see if password is all zeros
//First set the legth of temporary password string to have the same number of characters
//as possible password
SetLength(TempPassString,4);
//Set each character of the temporary password string.
//We read the characters from an array storing all posible hcaracters by specifying characters
//index position in that array
//NOTE Unless you are using newer versions of Delphi and compiling for Android first character
//in string has index of 1 so we have to add 1 to the Num1, Num2, Num3, Num4 value
TempPassString[1] := PossibleChars[Num1+1];
TempPassString[2] := PossibleChars[Num2+1];
TempPassString[3] := PossibleChars[Num3+1];
TempPassString[4] := PossibleChars[Num4+1];
//Check to see if temporary password string matches with the imput password string
if TempPassString = InputStr then
begin
//Set result to matching code
Result := TempPassString;
//Use Exit call to prematurely end the function so we don't waste time testing
//all remaining password combinations
Exit;
end;
//Custom counter implementation
while Result = '' do
begin
//Increase the last number count by one
Num4 := Num4+1;
//Check to see if the Num4 is greater than specific base number
//Base number is number of posible digit representations
//- 0 and 1 in Binary numeral system
//- 0 to 9 in Decimal numeral system
//- 0 to 9 and A B C D E F in HexDecimal numeral system
//In our case base number is the number of posible characters (Lenght of PossibleChars)
//If it is increase the Num3 and set Num4 to 0 just like you increase tens in Decimal
//numeral sytem and stes ones back to 0
if Num4 > Length(PossibleChars) then
begin
Num4 := 0;
Num3 := Num3+1;
//Check to see if Num3 is greater than specific base number
//If it is increase the Num2 by 1 and set Num3 back to 0
if Num3 > Length(PossibleChars) then
begin
Num3 := 0;
Num2 := Num2+1;
//Check to see if Num2 is greater than specific base number
//If it is increase the Num1 by 1 and set Num2 back to 0
if Num2 > Length(PossibleChars) then
begin
Num2 := 0;
Num1 := Num1+1;
end;
end;
end;
//Prepare temp password string for comparison
TempPassString[1] := PossibleChars[Num1+1];
TempPassString[2] := PossibleChars[Num2+1];
TempPassString[3] := PossibleChars[Num3+1];
TempPassString[4] := PossibleChars[Num4+1];
//Check to see if temporary password string matches with the imput password string
if TempPassString = InputStr then
begin
//Set result to matching code
Result := TempPassString;
//Use Exit call to prematurely end the function so we don't waste time testing
//all remaining password combinations
Exit;
end;
end;
end;
Пример использования
procedure TForm1.Button1Click(Sender: TObject);
var FoundPassword: String;
begin
FoundPassword := BruteForcePasswordFinder('59dg',CPossibleLowercaseLetersNumbersChars);
ShowMessage('Found password is: '+FoundPassword);
end;
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Причина, по которой я помещаю свой код в функцию, которая возвращает найденный код как результат String, заключается в том, что в реальном сценарии вы, вероятно, не сможете проверить свои пароли против фактического пароля (в противном случае во всем этом не будет необходимости), но Вы, вероятно, будете проверять, даст ли введенный угаданный пароль какой-либо другой алгоритм (например, алгоритм хеширования MD5), тот же результат, что и ваши вводные данные (большинство серверов хранят пароли в виде хеш-представлений и, таким образом, даже владельцы серверов не могут видеть, какой пароль на самом деле сохранены).
Начиная с Delphi XE7, вы можете использовать новую библиотеку параллельного программирования для запуска алгоритма с большим количеством потоков, используя TParallel.For:
TParallel.For (lowerBound, upperBound, Method);
Пример показан по адресу http://www.fmxexpress.com/fast-threaded-parallel-for-loop-in-delphi-xe7-firemonkey-on-android-ios-windows-and-osx/
TParallel.For(1, Max, procedure(I: Integer)
begin
if TryCode(I) then
begin
WriteLn(I);
end
end);
Однако я не вижу способа прервать параллельную обработку условно.