Пишем генератор по маске на delphi. Генератор слов, паролей, значений – целей может быть много.
В этой статье я хочу описать процесс написания такой программы как mr.gen.
Что и как делает программа читаем по ссылке, теперь по теме.
Задавшись целью написать генератор по маске на delphi, я стал чесать голову. Как же такое сделать? Что нужно требовать от бедного пользователя?
Я решил сделать чтобы нужно было указывать возможные символы на определенной позиции. Перечисляем возможные символы – пишем их подряд, далее ставим разделитель и описываем варианты следующего символа. Встал вопрос о разделителе – запятая? точка? дробь? А вдруг этот символ используется на какой-либо позиции? Как такое предотвратить?
Поначалу я собирался поставить еще какой-либо компонент для ввода разделителя, но посчитал это лишним. А что, если писать его перед маской? И красивее, и удобнее, так и поступил.
Итак, это присказка, сказка впереди.
[постановка задач]
Цель: написать генератор паролей по маске, принцип работы которого описан выше.
Задача 1: написать функцию считывания маски в массив строк с возможными комбинациями, в котором номер элемента соответствует позиции символа.
Задача 2: написать рекурсивную процедуру – основу генератора.
Задача 3: сохранение файла из массива, на этом не будем особо останавливаться.
[теоретическая часть]
Динамические массивы в delphi задаются так:
var arr:array of string;
мы будем использовать массивы строк.
SetLength(arr,10); – задание размера массива.
Length(arr); – получаем размер.
SetLength(arr,Length(arr)+1;) – удлинняем массив на один элемент.
arr:=nil; – обнуляем
[#1]
Задача 1. Парсим маску.
Введём массив строк marr для хранения маски.
А теперь начнём с самых простых процедур:
procedure AddMARR(item:string); var mlen:integer; begin mlen:=Length(marr); SetLength(marr,mlen+1); marr[mlen]:=item; end;
- добавляем элемент, переменную mlen вводим для того, чтобы Length(marr) вызывать один раз, а не два.
Теперь парсинг!
function FillMARR(tem:string):boolean; var det:char; mask:string; p:integer; buf:string; begin Result:=True; mask:=tem;
это мы начали функцию. Условимся, что возвращаем False если что-то не так, иначе True. Функции передаём маску, тут же присваеваем её переменной mask. det будет хранить разделитель, p – позицию, в buf будем что-то записывать временно.
Далее – так называемая защита от дурака, то есть от тех, кто забывает ввести маску или вводит ерунду. Плюс здесь же считаем разделитель, он – первый символ маски. Считаем и забудем о нём.
if Length(tem)<3 then begin
MessageBox(Application.Handle,'Mask too short','stopped',MB_ICONERROR);
Result:=False;
Exit;
end;
det:=tem[1];
Delete(mask,1,1);
if Pos(det+det,mask)<>0 then begin
MessageBox(Application.Handle,'Two delimiters near','stopped',MB_ICONERROR);
Result:=False;
Exit;
end;
(проверяем длину и отсутствие двух разделителей подряд)
Ну и теперь, потирая руки, тянем всю инфу из маски в наш массивчик:
p:=Pos(det,mask);
while p<>0 do begin
buf:=Copy(mask,1,p-1);
Delete(mask,1,p);
AddMARR(buf);
p:=Pos(det,mask);
end; // while
buf:=mask;
AddMARR(buf);
end;
немного неоптимизировано, но для небольшой маски вполне подойдёт.
Всё! Задачу 1 решили, можно проверять)
(c) crystalbit, http://parsers.info
Часть 2 на подходе, подпишись на rss и узнаешь первым;)
Постовой: покупка недвижимости Праги от Karlovy-Vary.ru – квартиры, дома и участки земли.