Password generator: Difference between revisions

Content added Content deleted
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 3,065: Line 3,065:
TcP73CJ@euFMjj
TcP73CJ@euFMjj
9%-tYX]z?8-xA5</pre>
9%-tYX]z?8-xA5</pre>

'''Alternative version.'''

This has the pretty much the same interface as, except the "count" parameter is mandatory.
The idea here is to have an infinite sequence of random password characters and
batch them up in groups of the wanted length.

<lang perl6>
subset MinumumPasswordLength of Int where * >= 4;
subset PositiveInt of Int where * > 0;

sub MAIN( PositiveInt :$c = 0, MinumumPasswordLength :$l = 8, Str :$x = '' )
{
.say for generate-passwords( $c, $l, char-groups( $x.comb ) );
}

sub char-groups( @exclude )
{
my %char-groups =
lc => ['a' .. 'z'],
uc => ['A' .. 'Z'],
digit => ['0' .. '9'],
special => < $ % & \ ` ~ ! * + , - . / : ; = ? @ ^ _ ~ [ ] ( ) { | } # ' " \< \> >;

%char-groups< special > = ( %char-groups< special > (-) @exclude ).keys
if @exclude;

%char-groups< special >:delete
unless %char-groups< special >;

%char-groups;
}

sub generate-passwords( UInt $count, UInt $length, %char-groups )
{
password-characters( %char-groups )
.batch( $length )
.map( *.pick: Inf ) # shuffle, so we don't get a predictable pattern
.map( *.join )
.head( $count );
}

sub password-characters( %char-groups )
{
gather loop {
take %char-groups{ $_ }.pick for %char-groups.keys
};
}

sub USAGE()
{
say qq:to/END/;
Specify a count: --c=1 (mandatory, at least 1),
Specify a length: --l=8 (default 8),
Specify characters to exclude: --x=... (must escape characters significant to the shell)
END
}
</lang>


=={{header|REXX}}==
=={{header|REXX}}==