Кто поможет в решение задачи на Turbo Pascal?

  • Автор темы Макс
  • Дата начала
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Задание

Помогите создать программу генератора паролей
он должен генерировать пароли длиной 8 символов,
соотношение паролей должно быть такое:
|0...9|-20% , |A...Z|-30% , |a...z|- 40 , |#...@|- 10%
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
uses crt;
const len=8; {длина пароля}
x=100; {кол-во создаваемых}
var
Dict, Pass : string;
i,j: integer;
f1 : text;
begin
assign(f1,'c:\passes.txt');
rewrite(f1); {создаем файл passes.txt}

Dict := 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789!@#$%^&*()+{}|":<>\/*-'; {это наш словарик}

Randomize; {включаем ГСЧ}

for i:=0 to x-1 do
begin
Pass:='';
for j:=0 to len-1 do Pass:=Pass+Dict[Random(75)+1]; {генерируем}
writeln(f1, Pass); {пишим в файл готовые пароли}
end;

close(f1); {закрываем файл}
end.

Вот на это у меня ума хватило, а как правильно реализовать процентное соотношение?
 
Тоха

Тоха

Новичок
Регистрация
29.07.2007
Сообщения
422
Реакции
0
Баллы
0
Генерируй его частями (две цифры затем большие буквы итд) и перед выводом перемешивай и объединяй все части. И используй регекспы))
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Генерируй его частями (две цифры затем большие буквы итд) и перед выводом перемешивай и объединяй все части. И используй регекспы))

ну хоть убей не доходит до меня...
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
|0...9|-20% , |A...Z|-30% , |a...z|- 40 , |#...@|- 10%
Как вариант-особо не изменяя твоего текста:
Измени словарик следующим образом:
Пусть в нём будет:
20 символов |#...@|,
80 символов |a...z|,
60 симоволов |A...Z|,
40 символов |0...9|.
Т.е. процентное соотношение вхождения каждого типа символов в общий словарь сохранено удовлетворяющим условию.
Теперь перемешай словарь и генерируй рандомизом 8 индексов массива, только уже(в данном случае) в диапазоне от 1 до 200 - по кол-ву элементов нового массива, последовательность значений по сгенерированным индексам и будет удовлетворять условию задачи. Тем более, что статистика вхождения каждого символа из конкретной группы символов условием не оговорены.

ЗЫ. randomize реализован убого и будет перекос полюбому, однако теоретически всё верно, т.е. удовлетворяет условиям - выровнять перекос можно опираясь на статистику вхождения символов, т.е. анализируя серию результатов. Добавляя или убирая со словаря символы того или иного типа.
Как вариант не идеален, но вполне имеющий право на существование и не требующий координального изменения твоего текста программы.
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
|0...9|-20% , |A...Z|-30% , |a...z|- 40 , |#...@|- 10%
Ещё вариант:
Создаёшь 4 словаря, а именно:
D1 = {0...9}
D2 = {A...Z}
D3 = {a...z}
D4 = {#...@}

Затем генерируешь рандомизом число от 1 до 10.
t := Random(9)+1

Далее анализ t:
Если 1 <= t <= 2, то для 1го символа пароля выбираешь рандомизом элемент массива D1.
Если 3 <= t <= 5, то для 1го символа пароля выбираешь рандомизом элемент массива D2.
Если 6 <= t <= 9, то для 1го символа пароля выбираешь рандомизом элемент массива D3.
Иначе для 1го символа пароля выбираешь рандомизом элемент массива D4.
И так далее все 8 символов пароля..
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Как вариант-особо не изменяя твоего текста:
Измени словарик следующим образом:
Пусть в нём будет:
20 символов |#...@|,
80 символов |a...z|,
60 симоволов |A...Z|,
40 символов |0...9|.
Т.е. процентное соотношение вхождения каждого типа символов в общий словарь сохранено удовлетворяющим условию.
Теперь перемешай словарь и генерируй рандомизом 8 индексов массива, только уже(в данном случае) в диапазоне от 1 до 200 - по кол-ву элементов нового массива, последовательность значений по сгенерированным индексам и будет удовлетворять условию задачи. Тем более, что статистика вхождения каждого символа из конкретной группы символов условием не оговорены.

ЗЫ. randomize реализован убого и будет перекос полюбому, однако теоретически всё верно, т.е. удовлетворяет условиям - выровнять перекос можно опираясь на статистику вхождения символов, т.е. анализируя серию результатов. Добавляя или убирая со словаря символы того или иного типа.
Как вариант не идеален, но вполне имеющий право на существование и не требующий координального изменения твоего текста программы.

Ещё вариант:
Создаёшь 4 словаря, а именно:
D1 = {0...9}
D2 = {A...Z}
D3 = {a...z}
D4 = {#...@}

Затем генерируешь рандомизом число от 1 до 10.
t := Random(9)+1

Далее анализ t:
Если 1 <= t <= 2, то для 1го символа пароля выбираешь рандомизом элемент массива D1.
Если 3 <= t <= 5, то для 1го символа пароля выбираешь рандомизом элемент массива D2.
Если 6 <= t <= 9, то для 1го символа пароля выбираешь рандомизом элемент массива D3.
Иначе для 1го символа пароля выбираешь рандомизом элемент массива D4.
И так далее все 8 символов пароля..

Это больно просто...
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Может кому пригодится, решили таким образом:

program PassWord;
const len=8; {длина пароля}
x=100; {кол-во создаваемых}
var
Dict,Dict2,Dict3,Dict4:string;
Pass:array[1..4] of string;
Pass2: array[1..4] of string;
i,j: integer;
f1 : text;
m1,m2,m3,m4:byte;
begin
assign(f1,'passes.txt');
rewrite(f1); {создаем файл passes.txt}
Dict:='qwertyuiopasdfghjklzxcvbnm';
Dict2:='QWERTYUIOPASDFGHJKLZXCVBNM';
Dict3:='0123456789';
Dict4:='!@#$%^&*()+{}|":<>\/*-'; {это наш словарик}

Randomize; {включаем ГСЧ}

for i:=0 to x-1 do begin
for j:=1 to 4 do begin Pass[j]:=''; Pass2[j]:=''; end;

for j:=0 to 2 do Pass2[1]:=Pass2[1]+Dict[Random(25)+1]; {генерируем}
for j:=0 to 1 do Pass2[2]:=Pass2[2]+Dict2[Random(25)+1];
for j:=0 to 1 do Pass2[3]:=Pass2[3]+Dict3[Random(9)+1];
Pass2[4]:=Pass2[4]+Dict4[Random(21)+1];

m1:=Random(3)+1;{генерируем место первой части кода}
Pass[m1]:=Pass2[1];
repeat
m2:=Random(3)+1;
until (m1<>m2);
Pass[m2]:=Pass2[2];

repeat
m3:=Random(3)+1;
until (m1<>m2)and(m1<>m3)and(m2<>m3);
Pass[m3]:=Pass2[3];

for j:=1 to 4 do
if(j<>m1)and(j<>m2)and(j<>m3)then m4:=j;
Pass[m4]:=Pass2[4];

writeln(f1, Pass[1]+Pass[2]+Pass[3]+Pass[4]); {пишим в файл готовые пароли}
end;

close(f1); {закрываем файл}
end.
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Вот ещё одна задача

это вообще жесть

Найти 23 простое шести разрядное число путём алгоритма "решета" Эротосфена
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
Ещё вариант:
Создаёшь 4 словаря, а именно:
D1 = {0...9}
D2 = {A...Z}
D3 = {a...z}
D4 = {#...@}

Затем генерируешь рандомизом число от 1 до 10.
t := Random(9)+1

Далее анализ t:
Если 1 <= t <= 2, то для 1го символа пароля выбираешь рандомизом элемент массива D1.
Если 3 <= t <= 5, то для 1го символа пароля выбираешь рандомизом элемент массива D2.
Если 6 <= t <= 9, то для 1го символа пароля выбираешь рандомизом элемент массива D3.
Иначе для 1го символа пароля выбираешь рандомизом элемент массива D4.
И так далее все 8 символов пароля..

Это больно просто...

Может кому пригодится, решили таким образом:

program PassWord;
const len=8; {длина пароля}
x=100; {кол-во создаваемых}
var
Dict,Dict2,Dict3,Dict4:string;
Pass:array[1..4] of string;
Pass2: array[1..4] of string;
i,j: integer;
f1 : text;
m1,m2,m3,m4:byte;
begin
assign(f1,'passes.txt');
rewrite(f1); {создаем файл passes.txt}
Dict:='qwertyuiopasdfghjklzxcvbnm';
Dict2:='QWERTYUIOPASDFGHJKLZXCVBNM';
Dict3:='0123456789';
Dict4:='!@#$%^&*()+{}|":<>\/*-'; {это наш словарик}

Randomize; {включаем ГСЧ}

for i:=0 to x-1 do begin
for j:=1 to 4 do begin Pass[j]:=''; Pass2[j]:=''; end;

for j:=0 to 2 do Pass2[1]:=Pass2[1]+Dict[Random(25)+1]; {генерируем}
for j:=0 to 1 do Pass2[2]:=Pass2[2]+Dict2[Random(25)+1];
for j:=0 to 1 do Pass2[3]:=Pass2[3]+Dict3[Random(9)+1];
Pass2[4]:=Pass2[4]+Dict4[Random(21)+1];

m1:=Random(3)+1;{генерируем место первой части кода}
Pass[m1]:=Pass2[1];
repeat
m2:=Random(3)+1;
until (m1<>m2);
Pass[m2]:=Pass2[2];

repeat
m3:=Random(3)+1;
until (m1<>m2)and(m1<>m3)and(m2<>m3);
Pass[m3]:=Pass2[3];

for j:=1 to 4 do
if(j<>m1)and(j<>m2)and(j<>m3)then m4:=j;
Pass[m4]:=Pass2[4];

writeln(f1, Pass[1]+Pass[2]+Pass[3]+Pass[4]); {пишим в файл готовые пароли}
end;

close(f1); {закрываем файл}
end.

БГГ))) Жги ещё! :a8e6cd7183adb9a51c1
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
А прально или непрально - это вопрос второстепенный, главное, что не слишком просто!))))))
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
А прально или непрально - это вопрос второстепенный, главное, что не слишком просто!))))))

Я знаю что там не совсем так, не не точное соотношение а примерное, есть некое отклонение, но я думаю это не страшно. Или есть что то ещё?

А ещё можно было решить всё гораздо проще, создать один словарик
но соотношение выражалось бы количественным соотношение символов, только вот я боюсь что такую строчку Паскаль не осилит, и придётся подключать дополнительную библиотеку длинных переменных.
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
Я знаю что там не совсем так, не не точное соотношение а примерное, есть некое отклонение, но я думаю это не страшно. Или есть что то ещё?

А ещё можно было решить всё гораздо проще, создать один словарик
но соотношение выражалось бы количественным соотношение символов, только вот я боюсь что такую строчку Паскаль не осилит, и придётся подключать дополнительную библиотеку длинных переменных.
Дык я ж об этом и сказал сразу, как самое простое решение. 200 символов осилит)
Камарад я тебе два правильных алгоритма написал.
А в представленном тобой листинге вместо 10% на {#...@}, приходится стабильно 12.5%. И вообще достаточно забавное построение последовательности)
Как говорится: английский я понимаю, но изъясняюсь на русском - так и тут: я понимаю все языки свободно, включая ассемблер, но изъясняюсь на семантике Си, поэтому если надо - я могу написать код обоих, представленных мной алгоритмов на C++ :)
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Дык я ж об этом и сказал сразу, как самое простое решение. 200 символов осилит)
Камарад я тебе два правильных алгоритма написал.
А в представленном тобой листинге вместо 10% на {#...@}, приходится стабильно 12.5%. И вообще достаточно забавное построение последовательности)
Как говорится: английский я понимаю, но изъясняюсь на русском - так и тут: я понимаю все языки свободно, включая ассемблер, но изъясняюсь на семантике Си, поэтому если надо - я могу написать код обоих, представленных мной алгоритмов на C++ :)

uses crt;
const len=8; {длина пароля}
x=100; {кол-во создаваемых}
var
Dict, Pass : string;
i,j: integer;
f1 : text;
begin
assign(f1,'c:\passes.txt');
rewrite(f1); {создаем файл passes.txt}

Dict := 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789!@#$%^&*()+{}|":<>\/*-'; {это наш словарик}

Randomize; {включаем ГСЧ}

for i:=0 to x-1 do
begin
Pass:='';
for j:=0 to len-1 do Pass:=Pass+Dict[Random(75)+1]; {генерируем}
writeln(f1, Pass); {пишим в файл готовые пароли}
end;

close(f1); {закрываем файл}
end.

Подскажи тогда как будет выглядеть строчка словарика если сделать всё банально просто. Точнее выражаясь как задать соотношение увлечением и уменьшением количества символов каждой группы?
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Дык я ж об этом и сказал сразу, как самое простое решение. 200 символов осилит)
Камарад я тебе два правильных алгоритма написал.
А в представленном тобой листинге вместо 10% на {#...@}, приходится стабильно 12.5%. И вообще достаточно забавное построение последовательности)
Как говорится: английский я понимаю, но изъясняюсь на русском - так и тут: я понимаю все языки свободно, включая ассемблер, но изъясняюсь на семантике Си, поэтому если надо - я могу написать код обоих, представленных мной алгоритмов на C++ :)

Напиши один пример только код целиком так как C++ я вообще далёк, что бы можно было посмотреть как работает. (Спасибо)
 
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
uses crt;
const len=8; {длина пароля}
x=100; {кол-во создаваемых}
var
Dict, Pass : string;
i,j: integer;
f1 : text;
begin
assign(f1,'c:\passes.txt');
rewrite(f1); {создаем файл passes.txt}

Dict := '$Dm9d8^nY4ep2qlh(suiQpWqEnRuTx!UjIO#PAyScbFeGoHaJK@LjZdXCV)BzN&sMJgHDW01w3i%5o67*8t01k2v3f4m5a6r7hl9'; {это наш словарик}

Randomize; {включаем ГСЧ}

for i:=0 to x-1 do
begin
Pass:='';
for j:=0 to len-1 do Pass:=Pass+Dict[Random(100)+1]; {генерируем}
writeln(f1, Pass); {пишим в файл готовые пароли}
end;

close(f1); {закрываем файл}
end.

Подскажи тогда как будет выглядеть строчка словарика если сделать всё банально просто. Точнее выражаясь как задать соотношение увлечением и уменьшением количества символов каждой группы?
Например вот чуть поправленный твой код :)
В нашем словаре, длинной 100 символов присутствуют:
|#...@|- 10 симоволов
|0...9| - 20 символов
|A...Z| - 30 символов
|a...z|- 40 симовлов.
Отбалды его перемешали и, полагая, что Randomize работает беспристрастно, общая статистика вхождения представителя каждой группы символов на 100 паролей будет верной)
 
OP
Макс

Макс

Активный участник
Регистрация
07.12.2006
Сообщения
7 393
Реакции
66
Баллы
48
Nusferatus

Nusferatus

Super Moderator
Регистрация
01.12.2006
Сообщения
40 161
Реакции
179
Баллы
63
Pest

Pest

Новичок
Регистрация
04.04.2007
Сообщения
3 364
Реакции
2
Баллы
0
Макс
Авто: Велосипед

зачем ты его тут изобретаешь?

unit Eratosthenes;

interface

type
TPrimeType = Cardinal;

TEratosthenesSieveLookupTableItem = record
Value: TPrimeType;
Next: Cardinal;
WheelIndex: Cardinal;
Incrementor: TPrimeType;
end;

TEratosthenesSieve = class(TObject)
private
FLookupTable: array of TEratosthenesSieveLookupTableItem;
FLookupTableSize: TPrimeType;
FLookupTableCapacity: TPrimeType;
FLookupTableCapacityStep: TPrimeType;
FWheelIndex: Cardinal;
FLookupTableLast: Cardinal;
FLookupTableFirst: Cardinal;
FCurrent: TPrimeType;
function LookupAppend: Cardinal;
function LookupInsert(from, k: Cardinal): Cardinal;
procedure LookupTableGrow;
procedure StrikeOut;
function CheckNext: boolean;
function Wheel(var WheelIndex: Cardinal): Cardinal;
procedure Spin;
protected
function GetCurrent: TPrimeType;
public
constructor Create;
destructor Destroy; override;
function Next: TPrimeType;
property LookupTableCapacityStep: TPrimeType read FLookupTableCapacityStep
write FLookupTableCapacityStep;
property Current: TPrimeType read GetCurrent;
end;

implementation

{ TEratosthenesSieve }

const
WheelSize = 48;
Wheel2357: array[0..WheelSize-1] of byte = (
2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,
6,4,6,2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10
);

function Increment(Incrementor: TPrimeType;
WheelValue: Cardinal): TPrimeType;
asm
test edx, edx
jp @1 // переходим, если 6 или 10
bsf ecx, edx // (2)=1, (4)=2, (8)=3
shl eax, cl
ret
@1: shl eax, 1
cmp edx, 6 // *2
jnz @2
lea eax, [eax+eax*2] // *3
ret
@2: lea eax, [eax+eax*4] // *5
end;

function TEratosthenesSieve.CheckNext: boolean;
begin
Spin; // Находим следующее число для проверки
Result:=FCurrent<FLookupTable[FLookupTableFirst].Value;
if Result then
LookupAppend
else
StrikeOut;
end;

constructor TEratosthenesSieve.Create;
const
PrimeFinderLookupTableCapacityStep = 5000;
begin
FLookupTableCapacityStep:=PrimeFinderLookupTableCapacityStep;
FCurrent:=1;
end;

destructor TEratosthenesSieve.Destroy;
begin
SetLength(FLookupTable, 0);
inherited;
end;

function TEratosthenesSieve.GetCurrent: TPrimeType;
begin
Result:=FCurrent;
end;

function TEratosthenesSieve.LookupInsert(from, k: Cardinal): Cardinal;
var
i: Cardinal;
KValue: TPrimeType;
KIncrementor: TPrimeType;
begin
Result:=k;
with FLookupTable[k] do begin
KValue:=Value;
KIncrementor:=Increment(Incrementor, Wheel2357[WheelIndex]);
end;
while true do begin
if from=High(Cardinal) then
i:=FLookupTableFirst
else
i:=FLookupTable[from].Next;
with FLookupTable do
if (Value>KValue) or ( (Value=KValue) and
(Increment(Incrementor, Wheel2357[WheelIndex])>KIncrementor) ) then begin
FLookupTable[k].Next:=i;
if from=High(Cardinal) then
FLookupTableFirst:=k
else
FLookupTable[from].Next:=k;
break;
end;
from:=i;
end;
end;

function TEratosthenesSieve.LookupAppend: Cardinal;
begin
if FLookupTableSize=FLookupTableCapacity then
LookupTableGrow;
if FLookupTableLast<>High(Cardinal) then
FLookupTable[FLookupTableLast].Next:=FLookupTableSize;
FLookupTableLast:=FLookupTableSize;
Inc(FLookupTableSize);
with FLookupTable[FLookupTableLast] do begin
Value:=FCurrent*FCurrent;
Next:=High(Cardinal);
WheelIndex:=FWheelIndex;
Incrementor:=FCurrent;
end;
Result:=FLookupTableLast;
end;

procedure TEratosthenesSieve.LookupTableGrow;
begin
Inc(FLookupTableCapacity, FLookupTableCapacityStep);
SetLength(FLookupTable, FLookupTableCapacity);
end;

function TEratosthenesSieve.Next: TPrimeType;
begin
case FCurrent of
1: FCurrent:=2;
2: FCurrent:=3;
3: FCurrent:=5;
5: FCurrent:=7;
7:
begin
FCurrent:=11;
FLookupTableFirst:=LookupAppend;
end;
else
repeat until CheckNext; // просеиваем решето, пока не найдем простое ч.
end;
Result:=FCurrent;
end;

procedure TEratosthenesSieve.StrikeOut;
var
k: Cardinal;
from: Cardinal;
begin
from:=High(Cardinal);
repeat
with FLookupTable[FLookupTableFirst] do begin
Inc(Value, Increment(Incrementor, Wheel(WheelIndex)));
k:=FLookupTableFirst;
FLookupTableFirst:=Next;
from:=LookupInsert(from, k);
end;
until FLookupTable[FLookupTableFirst].Value>Current;
end;

function TEratosthenesSieve.Wheel(var WheelIndex: Cardinal): Cardinal;
begin
Result:=Wheel2357[WheelIndex];
Inc(WheelIndex);
if WheelIndex=WheelSize then WheelIndex:=0;
end;

procedure TEratosthenesSieve.Spin;
begin
Inc(FCurrent, Wheel(FWheelIndex));
end;

end.
 
Верх Низ