diff options
| author | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-14 22:35:20 +0100 |
|---|---|---|
| committer | Jörg Sommrey <28217714+jo-37@users.noreply.github.com> | 2023-03-23 18:03:41 +0100 |
| commit | da8b19bdb5ac775e6091f8ebf934ed1266503ab7 (patch) | |
| tree | a5460e09691748a4af606727d27bc45baa0cb310 | |
| parent | ab930ab08e41408f9f01ac692af12c7d74a2bae4 (diff) | |
| download | perlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.tar.gz perlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.tar.bz2 perlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.zip | |
Challenge 015 task 2
| -rwxr-xr-x | challenge-015/jo-37/perl/ch-2.pl | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/challenge-015/jo-37/perl/ch-2.pl b/challenge-015/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..322f68876a --- /dev/null +++ b/challenge-015/jo-37/perl/ch-2.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl -s + +use v5.16; +use Test2::V0 '!float'; +use PDL; +use experimental 'signatures'; + +our ($tests, $examples, $decrypt, $key); + +run_tests() if $tests || $examples; # does not return + +die <<EOS unless @ARGV == 1 && $key; +usage: $0 -key=KEY [-decrypt] TEXT + +-key=KEY + use KEY for en-/decryption + +-decrypt + decrypt TEXT. (Default: encrypt) + +TEXT + en- or decrypt TEXT + +EOS + + +### Input and Output + +say vigenere($key, shift, !$decrypt); + + +### Implementation + +sub vigenere ($key, $text, $enc) { + # Convert the lowercase text to offsets from 'a'. + my $t = byte map ord() - ord('a'), split //, lc $text; + # Convert the lowercase key to offsets from 'a' and periodically + # extend it to text's length. + my $k = byte(map ord() - ord('a'), split //, lc $key) + ->range(0, $t->dim(0), 'p'); + + # Add or substract text and key, take the result mod 26 and convert + # back to characters. + join '', map chr($_ + ord('a')), (($t + (-1)**!$enc * $k) % 26)->list; +} + + +### Examples and tests + +sub run_tests { + SKIP: { + skip "examples" unless $examples; + + is vigenere('lemon', 'attackatdawn', 1), 'lxfopvefrnhr', + 'encoding example from Wiki'; + is vigenere('lemon', 'lxfopvefrnhr', 0), 'attackatdawn', + 'decoding example from Wiki'; + } + + SKIP: { + skip "tests" unless $tests; + } + + done_testing; + exit; +} |
