Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

First, let me congratulate Felonius on a very fine obfuscation.

However, The use of white space, while very commendable when writing "real" code, detracts a bit from the intended effect of the obfuscation. Here is your code with all the white space, a few semi-colons, and all the new lines removed. (It works exactly the same on my machine.)

#!/usr/bin/perl -w use strict; (sub{print map{$_->()}@_[3,1,2,0,4]})->(sub{no strict;q;read!;},sub{(s +ub{ map{$_->()}@_[2,1,0]})->(sub{'t '},sub{(sub{$_[0]->(),'s'})->(sub {'u' +})}, sub {'t','r'})},sub{(sub{map{$_->()," "}@_;})->(sub{lc ref sub{'', rev +erse 'J A P H !'}},sub{++($_="yot")},sub{(sub{@_[1,4,3,6,2,5,0]})->(split(' +', "thnva'e"))})},sub{(sub {map{$_->()}@_[1,0]})->(sub{(sub{$_[0]->(), q; +'t ; })->(sub{'n'})},sub{no strict;Do})},sub{$/})

I don't know if that really adds any mystery, but I think it makes it look more intimidating.


The main trick in this obfuscation comes from the idiom of calling a subroutine through a code reference like this $sub_ref->( 1, 2, 3 ). However, instead of defining a subroutine somewhere else and storing a reference to it in a scalar, you can define an anonymous code reference right where you are using it, like this ( sub{ print "@_" } ) -> ( 1, 2, 3 ). This has the exact same effect as print( 1, 2, 3 ). If you reformat the creation of the code reference the way Felonious does in the obfu it looks like this.

( sub { print "@_" } ) -> ( 1, 2, 3 );

Felonius takes this idea several steps further, starting with the idea of passing code-references/anonymous-subroutines as arguments to another anonymous subroutine. A simple example of this is:

( sub { print map { $_->() } @_; } ) -> ( sub{ 'Just ' }, sub{ 'another ' }, sub{ 'Perl ' }, sub{ 'hacker,' }, );

This code snippet creates a list of anonymous subroutines and passes it to another anonymous subroutine that just loops through the list calling each of the anonymous subroutines and collects all their output into another list. The resulting list is then printed.

The next devious step Feloius takes is to fiddle a bit with the order of the list of anonymous functions using Perl's slice syntax on the argument array before handing the list off to map. Applying this to the previous example yields something like this.

( sub { print map { $_->() } @_[1,0,3,2]; } ) -> ( sub{ 'another ' }, sub{ 'Just ' }, sub{ 'hacker,' }, sub{ 'Perl ' }, );

Then to top it all off, Felonious nests this entire construct inside itself. Here is another simplified example, which demonstrates this technique. <\p>

( sub { print map { $_->() } @_ } ) -> ( sub { ( sub { map { $_->() } @_ } ) -> ( sub { 'J' }, sub { 'A' } ) }, sub { ( sub { map { $_->() } @_ } ) -> ( sub { 'P' }, sub { 'H', '!' } ) } );

If you can figure that snippet out most of Felonious' obfuscation will become clear. Felonious nests it up to three levels deep in some places. Notice in the above snippet the nested constructs are wrapped in a sub{...} block (operator?, function?). This keeps the anonymous subroutine from being evaluated even though arguments are supplied. (Someone else probably has a better explanation for this.)

That explains most of the obfuscation. There are, however, two other tricks Felonius uses. First, Felonius uses Perl's string increment operator to turn "yot" into "you". This is what the line ++($_="yot") does. Then he gets the string "code" by calling ref on an anonymous subroutine, and lowercasing the result. This is what the following snippet does.

lc ref sub { '', reverse 'J A P H !' }

There are a few other tricks scattered around in the obfu, but if you understand the above tricks the rest of it should be relatively easy.

In reply to Re: (SPOILER) Read carefully... by meta4
in thread Read carefully... by Felonious

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others scrutinizing the Monastery: (9)
    As of 2018-06-25 14:33 GMT
    Find Nodes?
      Voting Booth?
      Should cpanminus be part of the standard Perl release?

      Results (126 votes). Check out past polls.