igoryonya has asked for the wisdom of the Perl Monks concerning the following question:

I've stumbled on: cat "test... test... test..." | '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see' I excluded 'perl -e' from the string after the pipe, because it's dangerous, so nobody tries it by copying/pasting.
I removed: cat "test... test... test..." because it's erroneous, because cat expects a file name, not a string, then 'perl -e' doesn't have '-n' parameter, which means nothing is being passed to perl from cat, so it's useless.
Then I've started deciphering:
$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see
I normalized ()?():() and s/// and y/// structures
So far, I've got this:
($?) ?(s/;s/s;;$?/) :(s//=]=>%-{<-|}<&|`{/); y/ -\/:-@[-`{-}/`-{\/" -/; s//$_/see
Since perl -e doesn't get any input to work on, i.e., $_ is empty and $? is always 0 in this code, so, the following part of a condition is always executed:
s//=]=>%-{<-|}<&|`{/
Which, I think, is equivalent to:
$_ =~ s//=]=>%-{<-|}<&|`{/;
so, the normalized code could be simplified to:
s//=]=>%-{<-|}<&|`{/; y/ -\/:-@[-`{-}/`-{\/" -/; s//$_/see
so, s/// would result in:
$_ = "=]=>%-{<-|}<&|`{";
Then, this string is translated with:
y/ -\/:-@[-`{-}/`-{\/" -/;
i printed $_ after y/// transliteration and it resulted in:
$_ = 'system"rm -rf /"';
Please explain, I don't understand, how y/// string above converted '=]=>%-{<-|}<&|`{' to 'system"rm -rf /"'

Update

So, thanx to LanX, I understood now, that the dashes in between of each of 2 characters represent ranges, so, I've manually converted the string with ranges to just a string:
my $r = ""; my $rs = q( -/:-@[-`{-}); $rs =~ s/(.)-(.)/r($1, $2)/ge; $rs =~ s/([-\/\\])/\\$1/g; print "$rs\n"; sub r{ my ($f, $t) = @_; my $s = ""; map { $s .= chr($_) } ord($f)..ord($t); return $s; }
and got the following string:
$_ = q/ !"#$%&'()*+,\-.\/:;<=>?@[\\]^_`{|}/;
and did the same thing with the replacement string: "`-{/" -" and got the following string:
$_ = q/`abcdefghijklmnopqrstuvwxyz{\/" \-/;
so, the translation string becomes:
y/ !"#$%&'()*+,\-.\/:;<=>?@[\\]^_`{|}/`abcdefghijklmnopqrstuvwxyz{\/" +\-/;
  • Comment on Please, help understanding y/// transliteration in this example (DON'T TRY executing oneliner)
  • Select or Download Code

Replies are listed 'Best First'.
Re: Please, help understanding y/// transliteration in this example (DON'T TRY)
by LanX (Saint) on Feb 05, 2020 at 01:55 UTC
    I think this is a pretty dangerous one liner!

    You should edit your post and strip at least the dangerous part from it, before someone tries to execute it.

    Regarding your question, B::Deparse shows the transliteration as (indentation and linebreaks added for clarity)

    tr ( -/:-@[-`{-}) [`-{/" \-] ;

    tr allows to define ranges with - , even outside alphabetic characters, such that you can translate

    • = to s
    • ] to y
    • and so on.

    like `-{ in the "to" part becoming the alphabet

    DB<11> print chr($_),"" for ord('`')..ord('{') `abcdefghijklmnopqrstuvwxyz{

    update

    flattening the "from" part

    DB<16> print chr($_) for map {ord($_->[0])..ord($_->[1])} [' ','/'], + [qw(: @)],[qw([ `)],[qw({ })] !"#$%&'()*+,-./:;<=>?@[\]^_`{|}

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      so,
      ' -/' ':-@' '[-`'
      and
      '{-}'
      are ranges?
      and in the replacement string:
      '`-{'
      is a range?
      I didn't know, you could use ranges in y///, I thought, y/// can have only 1 to 1 mappings, but it's pretty cool, that you can.
        yes!

        see my updates, it demonstrates how = becomes an s and ] becomes y ... etc

        just compare vertically.

        PS: Thanks for updating. :)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Please, help understanding y/// transliteration in this example (expanding transliterations)
by LanX (Saint) on Feb 05, 2020 at 12:23 UTC
    > so, the translation string becomes:

    Here a (Q&D) way to expand a tr expression:

    use strict; use warnings; use Data::Dump qw/pp dd/; my $from = q( -/:-@[-`{-}); my $to = q[`-{/" \-]; my @from = expand($from); my @to = expand($to); my %tr; @tr{@from} = @to; pp \%tr; sub expand { my $replace = shift; my $scale = join '' , 0..9,'a'..'z','A'..'Z'; my $code = qq( \$scale =~ tr($scale)($replace)d ); #pp $code; eval $code or warn $@; return split '', $scale; }

    -->

    { " " => "`", "!" => "a", "\"" => "b", "#" => "c", "\$" => "d", "%" => "e", "&" => "f", "'" => "g", "(" => "h", ")" => "i", "*" => "j", "+" => "k", "," => "l", "-" => "m", "." => "n", "/" => "o", ":" => "p", ";" => "q", "<" => "r", "=" => "s", ">" => "t", "?" => "u", "\@" => "v", "[" => "w", "\\" => "x", "]" => "y", "^" => "z", "_" => "{", "`" => "/", "{" => "\"", "|" => " ", "}" => "-", }

    DISCLAIMER: Neither complete nor even bullet proof.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Please, help understanding y/// transliteration in this example (DON'T TRY executing oneliner)(ppix regexp explainer)
by Anonymous Monk on Feb 05, 2020 at 04:30 UTC

    Hi

    Hmm, I never use transliterate, not exactly surprised , but sadly, PPI::Token::Regexp::Transliterate is not supported by PPIx::Regexp or ppixregexplain

    Note to self and maybe rt://PPIx-Regexp, look into this again at a later time

    Also curious B::Deparse does a lot of decoding/collapsing of tr, but doesn't offer an expanding :)

    " " => "`" # 32 => 96 "!" => "a" # 33 => 97 "\"" => "b" # 34 => 98 "#" => "c" # 35 => 99 "\$" => "d" # 36 => 100 "%" => "e" # 37 => 101 "&" => "f" # 38 => 102 "'" => "g" # 39 => 103 "(" => "h" # 40 => 104 ")" => "i" # 41 => 105 "*" => "j" # 42 => 106 "+" => "k" # 43 => 107 "," => "l" # 44 => 108 "-" => "m" # 45 => 109 "." => "n" # 46 => 110 "/" => "o" # 47 => 111 ":" => "p" # 58 => 112 ";" => "q" # 59 => 113 "<" => "r" # 60 => 114 "=" => "s" # 61 => 115 ">" => "t" # 62 => 116 "?" => "u" # 63 => 117 "\@" => "v" # 64 => 118 "[" => "w" # 91 => 119 "\\" => "x" # 92 => 120 "]" => "y" # 93 => 121 "^" => "z" # 94 => 122 "_" => "{" # 95 => 123 "`" => "/" # 96 => 47 "{" => "\"" # 123 => 34 "|" => " " # 124 => 32 "}" => "\\" # 125 => 92 undef => "-" # => 45

    m{[ -/][:-@][[-`][{-}]}; m{[`-{]/" \-};
      I don't think tr is classified as regex.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        Sure it is. I even linked it. PPI::Token::Regexp::Transliterate