Password generator: Difference between revisions

Content added Content deleted
m (Commodore BASIC - Minor clarification.)
(→‎functional: Raku alternate version upgraded to meet task specs)
Line 3,470: Line 3,470:


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


subset MinimumPasswordLength of Int where * >= 4;
{{improve|Raku|Does not check for, warn of, or forbid complete elimination of a required character category (as required by the task specs.)<br />Further, has very poor randomization. '''Every''' 8 character password has ''exactly'' 2 characters from each category. '''Every''' 12 character password has ''exactly'' 3 from each category, and they are always added in the same order.}}
subset NumberOfPasswords of UInt where * != 0;


sub MAIN( NumberOfPasswords: :c(:$count) = 1, MinimumPasswordLength :l(:$length) = 8, Str :x(:$exclude) = '' ) {
<lang perl6>
&USAGE() if 1 == (.comb ∖ $exclude.comb).elems for @char-groups;
subset MinimumPasswordLength of Int where * >= 4;
.say for password-characters($length, $exclude )
subset NumberOfPasswords of UInt where * != 0;
.map( *.split(' ') )

sub MAIN( NumberOfPasswords:D :c(:$count), MinimumPasswordLength :l(:$length) = 8, Str :x(:$exclude) = '' )
{
.say for password-characters( char-groups( $exclude.comb ) )
.batch( $length )
.map( *.pick: Inf ) # shuffle, so we don't get a predictable pattern
.map( *.pick: Inf ) # shuffle, so we don't get a predictable pattern
.map( *.join )
.map( *.join )
Line 3,486: Line 3,488:
}
}


sub char-groups( @exclude )
sub password-characters( $len, @exclude ) {
( (( char-groups($exclude) xx Inf ).map: *.pick).batch( 4)
{
state @char-groups =
Z~
(( char-groups($exclude, $len) xx Inf ).map: *.pick).batch($len-4) )
['a' .. 'z'],
['A' .. 'Z'],
['0' .. '9'],
< $ % & \ ` ~ ! * + , - . / : ; = ? @ ^ _ ~ [ ] ( ) { | } # ' " \< \> >;

@char-groups
.map( * (-) @exclude )
.grep( *.so );
}
}


multi char-groups( $exclude ) { | @char-groups.map( * (-) $exclude.comb ) }
sub password-characters( @char-groups )
multi char-groups( $exclude, $max-weight ) { flat (char-groups($exclude)>>.keys.map: {$_ xx ^$max-weight .roll}) }
{
( |@char-groups xx Inf ).map: *.pick;
}
</lang>


sub USAGE() {
say qq:to/END/;
Specify a length: -l=10 (minimum 4)
Specify a count: -c=5 (minimum 1)
Specify characters to exclude: -x=xkcd (optional)
Password must have at least one of each: lowercase letter, uppercase letter, digit, punctuation.
END
}</lang>
'''Sample output:'''
'''Sample output:'''


Without parameters:
Without parameters:
<pre>
<pre>d[G2r4;i</pre>
Usage:
genpwd.raku [-c|--count=<NumberOfPasswords>] [-l|--length=<MinimumPasswordLength>] [-x|--exclude=<Str>]
</pre>


With passed parameters: -c=1
With passed parameters: -c=5 -l=12 -x=aeiou
<pre>Jk&>Az22</pre>
<pre>x7)YbEZQ2xp2
CEpZ>#4'rO7d
With passed parameters: -l=4 -c=5 -x=abcdefghijklmnopqrstuvwxy
pn(5B;wb66DM
<pre>
KA;3T7=s+I5{
zH5^
LL<tB~L1~Y*q</pre>
4zT;
9/zJ
z6_U
!zC8
</pre>


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