Home > Raku > Antipairing

Antipairing

As suspicious questions on IRC and Discord revealed, there are quite a few solutions to the PWC that are not made public. One question in particular indicates that there is a build-in missing in Raku.

Nemokosch: let’s say I have a 5×5 table for some reason

PWC162-2 is asking to implement an encryption algorithm that uses a simple substitution table. Having a data-struction that allowes to turn a character into a 2-dimensional @index and then use it to @replacement[||@index] would be very helpful indeed. We can use .antipairs to turn a simple list into something we can assign to a Hash and be done with it. With 2-dimension, we have to create our own.

proto sub deepantipairs(@positional, $dimensions --> Positional) {*}
multi sub deepantipairs(@a, 2) {
    @a.pairs.map({ my $outer-key = .key; .value.antipairs.map({ .key => ($outer-key, .value) }) }).flat
}
my $phrase = 'Spring has sprung!';
my @table = flat($phrase.lc.comb.grep(/\w/), 'a'..'z').unique[^25].batch(5);
my %antitable = @table.&deepantipairs(2);

# OUTPUT:

# Array @table = [("S", "p", "r", "i", "n"), ("g", "h", "a", "s", "u"), ("!", "b", "c", "d", "e"), ("f", "j", "k", "l", "m"), ("o", "q", "t", "v", "w")]
# Hash %antitable = {"!" => $(2, 0), :S($(0, 0)), :a($(1, 2)), :b($(2, 1)), :c($(2, 2)), :d($(2, 3)), :e($(2, 4)), :f($(3, 0)), :g($(1, 0)), :h($(1, 1)), :i($(0, 3)), :j($(3, 1)), :k($(3, 2)), :l($(3, 3)), :m($(3, 4)), :n($(0, 4)), :o($(4, 0)), :p($(0, 1)), :q($(4, 1)), :r($(0, 2)), :s($(1, 3)), :t($(4, 2)), :u($(1, 4)), :v($(4, 3)), :w($(4, 4))}

Let’s rotate the table (the basic idea behind the Enigma) to create a much more interesting cypher-text.

sub encrypt($phrase, $text --> Str) {
    my @table = flat($phrase.lc.comb.grep(/\w/), 'a'..'z').unique[^25].batch(5);
    my %antitable = @table.&deepantipairs(2);

    my $retval;

    for $text.lc.comb.grep(/\w/) -> $char {
        my @deepindex := %antitable{$char};
        $retval ~= @table[||@deepindex];
        @table = @table».List.flat[1..*,0].flat.batch(5);
    }

    $retval
}

say encrypt($phrase, 'As suspicious questions on IRC and Discord revealed, there are quite a few solutions to the PWC that are not made public. One question in particular indicates that there is a build-in in Raku missing.');

# OUTPUT:
# aprdnhbmdrodhvpkdtdxtjpppcuhjkuhmpdvfybpwannjpuychrfvdasojvvadgnwcqcwqkjmndpxexcepjcvjnagvpiopidyalietcknsbseejeqkbopsbpwypbrcuwknsejinlxjsmkxppwdasrrniboewbauejl

Please note the tripple “p” in the cypher. By rotating the replacement table, we mess up statistical properties of the natural language we encrypt. This makes limiting the key-space much harder.

As you likely spotted, I defined a proto with the argument $dimensions (our item may be an Iterable so we can’t infer this argument). Raku has many very handy methods defined in List that work very well with a single dimension. There may be more work to do when we start to support fixed size shaped arrays well.

Categories: Raku
  1. No comments yet.
  1. May 2, 2022 at 18:57

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: