aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-03-14 22:35:20 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2023-03-23 18:03:41 +0100
commitda8b19bdb5ac775e6091f8ebf934ed1266503ab7 (patch)
treea5460e09691748a4af606727d27bc45baa0cb310
parentab930ab08e41408f9f01ac692af12c7d74a2bae4 (diff)
downloadperlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.tar.gz
perlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.tar.bz2
perlweeklychallenge-club-da8b19bdb5ac775e6091f8ebf934ed1266503ab7.zip
Challenge 015 task 2
-rwxr-xr-xchallenge-015/jo-37/perl/ch-2.pl66
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;
+}