Аудиозапись 09_01, 09_02, 09_03, 09_04.
Примечание 0. Очевидно, в качестве первого параметра EXEC пришлось указать command.com потому, что это в DOS и Win9x он был запущен постоянно, а в WinNT его надо предварительно запускать, перед выполнением нужной программы.
Примечание 1. Если после экспериментов с циклом (и некорректных выходов из него) остались файлы вида TP0B3FF1.$$$, то их можно удалять.
Примечание 2. Резко ускорить работу программы можно, если архиватор и взламываемый файл расположить на виртуальном диске (в оперативной памяти).
Примечание 3. В какой-то момент я попытался прервать выполнявшийся цикл нажатием на Ctrl-PauseBreak, PauseBreak. После этого в DOS-режиме машина перешла в пошаговый режим, (Ctrl-C - переход к следующему шагу), не помогла даже перезагрузка. Помогло только повторное нажатие на Ctrl-PauseBreak, PauseBreak.
Примечание 4. Когда будет найден правильный пароль, программа не сможет продолжить выполнение, так как она попытается перезаписать файл 123.txt, а пользователь не будет понимать, что от него хотят, так как это попадает в report.txt.
Примечание 5. Я выяснил, что пароль вида ">..." WinRAR принимать отказывается. Поэтому, я решил убрать символ > (i=62), но к, сожалению, внутри цикла условие вида if i=62 then i:=63 работать не смогло. Это та ситуация, когда для организации цикла перебора выгоднее было бы пользоваться циклом на метках и операторах goto, что позволит вручную наращивать счётчики для обхода неиспользуемых областей таблицы символов.
Задание. Создайте такой алгоритм перебора, чтобы мог подбираться пароль любой длины.
Решение 1. "Дубовое".
Изначально сделать 6 вложенных циклов. Всё-равно пароль длиннее 6 символов будет подбираться годы.
Недостаток, пароли от 1-го до 5 символов подбираться не будут. Для решения этого недостатка счётчики i, j и прочие при передаче в переменную пароля будут проходить обработку, если счётчик =0, то никакой символ в пароль не должен ставится.
Решение 2. Перебор с анализом содержимого переменной пароля.
Пояснения. Используем строчную переменную password.
Используем ЕДИНСТВЕННЫЙ цикл наращения этой переменной.
Пусть в какой-то момент password='75Fg}'.
Узнаём текущую длину пароля len_p=password[0];
Извлекаем код последнего символа в переменной chr_m:=chr(password[len_p])
Если он < 127, то увеличиваем его на единицу и возвращаем в переменную password[len_p]:= ord (chr_m+1);
В противном случае ПРОЦЕДУРА НАРАШЕНИЕ СИМВОЛА. Сбрасываем код текущего символа к минимальному возможному значению password[len_p]:= ord (33) и производим проверки:
Всё мозги клинит, но прога работает, по крайней мере символа на 3- 4. См. рис.1.
Решение 3. Косвенная рекурсия (рекурсия - это ссылка на само себя, абсолютное большинство языков программирования прямую рекурсию запрещают).
Создать процедуру. Которая на входе будет получать в себя указание номера символа,
который нужно нарастить. Она будет наращивать этот символ, а в случае его максимального
значения, выставлять ему минимальное значение. В случае выполнения последнего
действия, она будет возвращать в основную программу указание на то, что нужно
наращивать символ левее (переменная вида LEVEE=истина). Основная программа,
увидев это указание должна уменьшить номер текущего символа на единицу (то есть
взять символ левее), обнулить переменную взаимодействия (LEVEE=ложь) и заново
запустить ту же процедуру.
См. рис.2.
К маленьким дополнениям. В процедуре должна быть проверка на то, что текущий обрабатываемый символ не равен нулю. Иначе должен добавляться минимальный символ левее всех существующих. Сразу после этого должен происходить сборс переменной LEVEE=ложь и выход из процедуры, без всех иных действий.