RosettaCodeData/Task/Password-generator/Pascal/password-generator-2.pas

144 lines
3.6 KiB
ObjectPascal

PROGRAM pwgen;
(*)
Free Pascal Compiler version 3.2.2 [2024/05/01] for x86_64
Free to use, as is, experimental , different take on the parameter boilerplate stuff..
directives:
https://www.freepascal.org/docs-html/prog/progch1.html
The free and readable alternative at C/C++ speeds
compiles natively to almost any platform, including raspberry PI *
Can run independently from DELPHI / Lazarus
https://www.freepascal.org/advantage.var
(*)
{$IFDEF FPC}
{$mode objfpc} (*) directive to be used for defining classes (*)
{$LONGSTRINGS ON} (*) aka {H+} = ansistrings (*)
{$RANGECHECKS ON} (*) aka {$R+} (*)
{$S+} (*) stack checking on (*)
{$TYPEDADDRESS ON} (*) aka {$T+} (*)
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
{$MACRO ON}
{$DEFINE crlf := #13#10 }
{$DEFINE tab := #9 }
{$DEFINE quot := #39 }
{$DEFINE dquot := #34 }
{$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined} // Use for variants, complex numbers
USES
crt,
Math,
SysUtils,
TypeUtils
;
TYPE
List = array of string ;
// Mod to change printing behaviour of plural
OPERATOR * (const A: char; const B: boolean): char;
BEGIN IF B = True THEN Result := A ; END;
// Oneline if-then-else
FUNCTION IIF ( Cond: boolean; A, B: variant ) : variant ;
BEGIN IF ( Cond ) THEN IIF := A ELSE IIF := B ; END ;
// Mod to change behaviour, needed in GetPVal
OPERATOR IN (const A: string; const B: string): integer;
BEGIN Result := pos( A, B ) ; END;
// Mod for options
FUNCTION GetPVal ( parm:string; opt:string): integer;
BEGIN
GetPVal := opt in parm;
IF GetPVal > 0 THEN
GetPVal:= ( StrToIntDef( Copy( parm, Min( High( parm ), GetPVal + 2 ) ).Split(' ')[0], 0 ));
END;
FUNCTION PickFrom ( S: string ): char;
BEGIN PickFrom := S[ math.RandomRange( Low(S), high(S) ) ] ; END;
(*) MAINLINE (*)
VAR
L: List ;
_: string ;
S: string ;
excluding : array of char = ( '|','I','l','1','O','0','5','S','Z','2' ) ;
numb3rs: string = '0123456789';
l3tters: string = 'abcdefghijklmnopqrstuvwxyz';
speci4ls: string = '!"#$%&''()*+,-./:;<=>?@[]^_{|}~';
j,k: integer;
n: integer = 1;
w: integer = 17;
parm: string = '';
BEGIN
Randomize;
FOR k := 1 TO paramcount() DO
parm := parm + paramstr( k ) + ' ' ;
IF '-h' IN parm > 0 THEN
BEGIN
WriteLn ( crlf , 'pwgen -[hwren]', crlf ) ;
WriteLn ( 'Generates random passwords.' , crlf , 'Without options it generates ', n ,' password', 's' * (n > 1),', of width ', w , '.', crlf ) ;
WriteLn ( 'options: -h(elp), -w(idth of password [ 8 to 500 ] ), -r(andom seed), -e(xlude lookalikes), -n(r of passwords [ 1 to 500 ])', crlf ) ;
WriteLn ( 'ex. : ./pwgen -n7 -w15 -r17', crlf ) ;
Exit();
END; // IF '-h' IN parm
n := IIF ( GetPVal ( parm, '-n') = 0, n, Min ( 500, Max ( GetPVal ( parm, '-n'), 1) ) ) ;
w := IIF ( GetPVal ( parm, '-w') = 0, w, Min ( 500, Max ( GetPVal ( parm, '-w'), 8) ) ) ;
RandSeed := IIF ( GetPVal ( parm, '-r') = 0, RandSeed, GetPVal ( parm, '-r') ) ;
FOR j := 1 TO n DO
BEGIN
S:='';
FOR k := 0 TO w DO
S := S + PickFrom( numb3rs ) + PickFrom( l3tters ) + PickFrom( speci4ls ) + PickFrom( UpperCase( l3tters ) );
IF '-e' IN parm > 0 THEN
BEGIN
L := S.Split( excluding) ;
FOR _ in L DO
S := S + _ ;
END; // IF '-e' IN parm
WriteLn( copy( S, math.RandomRange ( Low( S ), High( S ) - w ), w ) );
END; // FOR j := 1
END. (*) Of PROGRAM pwgen.pas (*)
(*)