diff options
| -rw-r--r-- | challenge-287/peter-campbell-smith/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-287/peter-campbell-smith/perl/ch-1.pl | 69 | ||||
| -rwxr-xr-x | challenge-287/peter-campbell-smith/perl/ch-2.pl | 40 |
3 files changed, 110 insertions, 0 deletions
diff --git a/challenge-287/peter-campbell-smith/blog.txt b/challenge-287/peter-campbell-smith/blog.txt new file mode 100644 index 0000000000..de7d8209d9 --- /dev/null +++ b/challenge-287/peter-campbell-smith/blog.txt @@ -0,0 +1 @@ +http://ccgi.campbellsmiths.force9.co.uk/challenge/287 diff --git a/challenge-287/peter-campbell-smith/perl/ch-1.pl b/challenge-287/peter-campbell-smith/perl/ch-1.pl new file mode 100755 index 0000000000..4d674c0ee3 --- /dev/null +++ b/challenge-287/peter-campbell-smith/perl/ch-1.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge + +use v5.26; # The Weekly Challenge - 2024-09-16 +use utf8; # Week 287 - task 1 - Strong password +use warnings; # Peter Campbell Smith +binmode STDOUT, ':utf8'; + +strong_password('aaabbbcccccc', '4 triplets, no upper or digit'); +strong_password('123abcdef', 'no upper case'); +strong_password('abcdefghijkl', 'no upper or digit'); +strong_password('ABCD5aa6FGHI', 'no change needed'); +strong_password('Mi5', 'too short'); +strong_password('', 'null'); + +sub strong_password { + + my ($password, $comment, $steps, @upper, @lower, @digit, $props, $r, $insert, $length); + + ($password, $comment) = @_; + $steps = 0; + @upper = ('A' .. 'Z'); + @lower = ('a' .. 'z'); + @digit = ('0' .. '9'); + + # stage 1 - deal with triplets + while (1) { + $props = assess($password); + $r = $props->{triplet}; + last unless $r; + $insert = ''; + do { + $insert = $digit[rand(10)] unless $props->{digit}; + $insert = $lower[rand(26)] unless $props->{lower}; + $insert = $upper[rand(26)] unless $insert; + } until $insert ne $r; + $password =~ s|$r$r$r|$r$r$insert$r|; + $steps ++; + } + + # stage 2 - append any missing class of character + $length = length($password); + $password .= $lower[rand(26)] unless $props->{lower}; + $password .= $upper[rand(26)] unless $props->{upper}; + $password .= $digit[rand(10)] unless $props->{digit}; + + # stage 3 - pad if necessary to 6 chars + $password .= $lower[rand(26)] while length($password) < 6; + $steps += length($password) - $length; + + say qq[\nInput: \$password = '$_[0]' ($comment)]; + say qq[Output: '$password'] . + qq[ after $steps step] . ($steps == 1 ? '' : 's'); +} + +sub assess { + + my ($password, %props); + + # get properties of password + $password = $_[0]; + $props{lower} = $password =~ m|[a-z]|; + $props{upper} = $password =~ m|[A-Z]|; + $props{digit} = $password =~ m|[0-9]|; + $props{triplet} = $password =~ m|(.)\1\1| ? $1 : ''; + return \%props; +} + diff --git a/challenge-287/peter-campbell-smith/perl/ch-2.pl b/challenge-287/peter-campbell-smith/perl/ch-2.pl new file mode 100755 index 0000000000..e1ba919f76 --- /dev/null +++ b/challenge-287/peter-campbell-smith/perl/ch-2.pl @@ -0,0 +1,40 @@ +#!/usr/bin/perl + +# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge + +use v5.26; # The Weekly Challenge - 2024-09-16 +use utf8; # Week 287 - task 2 - Valid number +use warnings; # Peter Campbell Smith +binmode STDOUT, ':utf8'; + +my @tests; + +say qq[\nValid numbers:\n \$str Valid?\n ----- ------]; +@tests = ('23', '-23', '+23', '34.1', '-34.1', '+34.1', '.7', '-.7', '23e0', '23e-1', '23E+2', '-23e10', '+34.5e-10'); +valid_number($_) for @tests; + +say qq[\nInvalid numbers:\n \$str Valid?\n ----- ------]; +@tests = ('two', '23-', '23.1.2', 'e', 'e1', '34e1.2', '34e++6', '.e5', '+.e5', '123E', '.', '.e6' ); +valid_number($_) for @tests; + +sub valid_number { + + my ($str, $str2, $valid, $a, $b); + + $str = $_[0]; + $valid = 0; + + # basic match $a------------ $b----- + if (($a, $b) = $str =~ m|^([-+]?\d*\.?\d*)([Ee]?.*)$|) { + + # but if [Ee] is present it must be followed by optional sign and 1+ digits + $valid = 1 if ($b eq '' or ($a ne '' and $b =~ m|^[Ee][-+]?\d+$|)); + } + + # decimal point must be preceded or followed by a digit (or both) + if ($valid and $str =~ m|\.|) { + $valid = 0 unless ($str =~ m|\d\.| or $str =~ m|\.\d|); + } + + printf("%10s %10s\n", $str, ('false', 'true')[$valid]); +} |
