Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

I refuse to explain this

by Dominus (Parson)
on Apr 09, 2001 at 05:24 UTC ( #70901=obfuscated: print w/ replies, xml ) Need Help??

require 5.00553; use re 'eval'; $|=1;$^W=0; $z = qr{(?{local$d=1}) (?:`(?{$d++}) |.(?{$d--}) )+? (?(?{$d})(?!)) }x; $_="``As`SB``Ad``S``BS`BBI``Ae``B`SI`Ed``A?``C``CIi`pI``E? Z``BZZZZZ`KI```CX`KIZZQZZZQZZZZZQZZZZQZ``BZZ```CX`KX`KXQ`` Ee``EeZZZZZQZ```CX`KIZZQ```CX`KIZZQZZZZQ```CXZ`KIZZQ``Ee`` `CX`KIZZQ``EdZZZQZ``BZZ```CX`KX`KXQ``BZ```CX`KIZZ`KXZQ``Ee ```CX`KIZZQ``EdZZZQ``BZZZZ`KXQZ``BZZ```CX`KX`KXQ``B```CXZ` KIZZ`KXQ``Ee``EeZZZZZQ``B``EeZZZ`KXQ``Ee``EdZZZQ``Ee```CX` KIZZQ``EdZZZQ``Ed``Ee```CX`KX`KI"; s/\n//g;s/Q/`KI``E?/g;s/X/IZZZ/g;s/Z/``Es/g; do { $N=0; s{`I($z) (?{$q=0})|``K($z)($z) (?{$q=1}) |```S($z)($z)($z)(?{$q=2})|```B($z)($z)($z) (?{$q=3}) |```C($z)($z)($z)(?{$q=4})|``A($z)($z) (?{$q=5}) |`i($z) (?{$R++,$q=6})|`p($z)(?{print(chr 120-$R), $R=0, $q=7}) |`E($z) (?{$q=8})|`V($z) (?{$q=9}) } {$N=1; $q<5 ?($1,$2,"``$4$6`$5$6","`$7`$8$9","``$10$12$11")[$q] :$q==5?($bind{$13}=$14,"") :($15,"",$bind{$17},"")[$q-6] }ex; } while $N; __END__
Good luck. (Snort!)

Comment on I refuse to explain this
Download Code
Re: I refuse to explain this
by strredwolf (Chaplain) on Apr 09, 2001 at 07:04 UTC
    The main key behind it is the use re 'eval', which allows Perl to be inside the (?{...}) considitonal regexps. Couple that with the "e" flag on s/// and it runs the loop. Now when it hits the do{}while($n), $_ is
    ``As`SC``Ad``S``CS`CCI``Ae``C`SI`Ed``A?``B``BIi`pI``E?``Es``C``Es``Es` +`Es``Es``Es`KI```BI``Es``Es``Es`KI``Es``Es`KI``E?``Es``Es``Es`KI``E?` +`Es``Es``Es``Es``Es`KI``E?``Es``Es``Es``Es`KI``E?``Es``C``Es``Es```BI +``Es``Es``Es`KI``Es``Es``Es`KI``Es``Es``Es`KI``E?``Ee``Ee``Es``Es``Es +``Es``Es`KI``E?``Es```BI``Es``Es``Es`KI``Es``Es`KI``E?```BI``Es``Es`` +Es`KI``Es``Es`KI``E?``Es``Es``Es``Es`KI``E?```BI``Es``Es``Es``Es`KI`` +Es``Es`KI``E?``Ee```BI``Es``Es``Es`KI``Es``Es`KI``E?``Ed``Es``Es``Es` +KI``E?``Es``C``Es``Es```BI``Es``Es``Es`KI``Es``Es``Es`KI``Es``Es``Es` +KI``E?``C``Es```BI``Es``Es``Es`KI``Es``Es`KI``Es``Es``Es``Es`KI``E?`` +Ee```BI``Es``Es``Es`KI``Es``Es`KI``E?``Ed``Es``Es``Es`KI``E?``C``Es`` +Es``Es``Es`KI``Es``Es``Es`KI``E?``Es``C``Es``Es```BI``Es``Es``Es`KI`` +Es``Es``Es`KI``Es``Es``Es`KI``E?``C```BI``Es``Es``Es``Es`KI``Es``Es`K +I``Es``Es``Es`KI``E?``Ee``Ee``Es``Es``Es``Es``Es`KI``E?``C``Ee``Es``E +s``Es`KI``Es``Es``Es`KI``E?``Ee``Ed``Es``Es``Es`KI``E?``Ee```BI``Es`` +Es``Es`KI``Es``Es`KI``E?``Ed``Es``Es``Es`KI``E?``Ed``Ee```BI``Es``Es` +`Es`KI``Es``Es``Es`KI

    Hmmm, it looks like a bit of source code and a state engine to me!

    --
    $Stalag99{"URL"}="http://stalag99.keenspace.com";

      Says strredwolf:
      The main key behind it is the use re 'eval', which allows Perl to be inside the (?{...}) considitonal regexps.
      No, that is not what use re 'eval' does; I suggest you consult the manual.

      The use re 'eval' is not really necessary to the program; it is only there to allow me to make the code simpler by abbreviating the regex.

      Hmmm, it looks like a bit of source code and a state engine to me!
      Nope, totally wrong! (Except perhaps in the trivial sense that every program is a 'state engine'.)
        I did. But I'll agree that it's helps shorten it (sub in regexp?).

        But expanding $_ out does make it look like you're doing a virtual machine inside of the s///ex regexp. Source code (or is it VM machine code?) and a state engine, like my own obfusc.

        --
        $Stalag99{"URL"}="http://stalag99.keenspace.com";

      Hmmmm, looks kinda like unlambda (the lower case, anyway).

      p
        Says petral:
        looks kinda like unlambda
        Wow, great catch!

        I had forgetten all about unlambda, and I owe you big thanks for reminding me. You are absolutely correct. You can think of this program as an interpreter for a language very similar to unlambda. In particular, the I, `, S, and K have exactly the same meaning as in unlambda.

        Now I don't have to refuse to explain the program; I can just point to the unlambda web pages. There are a bunch of variations here, but if you understand unlambda, it should be easy to understand this program. (That is something of a poisoned apple, because hardly anyone does understand unlambda.)

        Everyone should give petral a big ++ on this for being so clever.

Re: I refuse to explain this
by grinder (Bishop) on Apr 09, 2001 at 12:25 UTC

    Had to -- this one as I can't get it to run. It just spews out

    Use of uninitialized value in concatenation (.) at dominus line 10.
    interspersed with the odd
    Use of uninitialized value in hash element at dominus line 10.
    man I hate when that happens.

    Update: My bad. I didn't realise that the script has to be run with warnings turned off. But Dominus' standing notwithstanding (hey, I'm on his book mailing list ferchrissakes) I -- obfuscations that don't run correctly with warnings enabled.
    --
    g r i n d e r
Re: I refuse to explain this
by MrNobo1024 (Hermit) on Apr 10, 2001 at 01:09 UTC
    When I run this nothing happens. Is there supposed to be a /x modifier on the qr//?
      No, it should be clean, from what I have.

      --
      $Stalag99{"URL"}="http://stalag99.keenspace.com";

      I put in the 'x' modifier on the qr//, and it has fixed it. Looks like Dominus' update is causing some confusion.
         MeowChow                                   
                     s aamecha.s a..a\u$&owag.print
      Says MrNobo1024:
      Is there supposed to be a /x modifier on the qr//?
      Yes, just so. My apologies; I decided to fix up the formatting, and I didn't test it properly after I had done so.

      When I put in the /x, it works correctly.

Re (tilly) 1: I refuse to explain this
by tilly (Archbishop) on Apr 10, 2001 at 01:42 UTC
    FWIW I ran this with 5.6 on Linux and it is a standard JAPH. (Ran a little slowly, but oh well.)

    I just thought a success report would make sense when everyone else is reporting failure.

      Hmm... it worked for me yesterday, but Dominus changed the formatting today, and I'm now getting the same results as MrNobo1024.
      Says tilly:
      Ran a little slowly...
      It is doing a lot of computation. I did put in an optimization that makes it somewhat smaller and faster; perhaps you ran the original version.

      Actually by observing which parts are printed quickly and which are printed slowly get can get a better notion of what the program is going.

Re: I refuse to explain this
by MeowChow (Vicar) on Apr 10, 2001 at 03:13 UTC
    We give up. Start explaining =)
      Says MeowChow:
      Start explaining =)
      I'm not refusing to explain out of spite. I'm refusing because I can't explain it. Explaining would require an eight- to ten-thousand word article. I know that, because I once wrote the first half of such an article, and it was 4,700 words long.

      So this one is going to have to wait for someone who is a better explainer than I am.

Re: I refuse to explain this
by jynx (Priest) on Apr 13, 2001 at 00:43 UTC

    i'm probably completely off, but it seems to iterate over $_, slowly changing it as it goes along. The two important parts seem to be:
    # this increments $R, which tells us which character we're going to pr +int |`i($z) (?{$R++,$q=6) # it tells us that through this snippet: `p($z)(?{print(chr 120-$R),$R=0,$q=7})
    So whenever the substitution matches a `i($z) it'll increment $R, and once that gets incremented enough times the RE will match (at some point before matching `i again) `p($z).

    $z seems to just match any number of backticks (and $d is set to 2, although this doesn't need to happen) or any number of characters, and $d is set to zero. $d is important because (if i'm reading this right) when there are only backticks left, $z won't match because of the $d flag. This is what will eventually stop the do{}while loop (i think).

    The only thing i'm hazy about (other than the whole thing :-) is %bind. Because of it's use you can't use strict, because i don't see it in the built-ins in camel3. And i'm not sick enough to looptrace far enough to find out what $14 and $17 and whatnot else might actually be to see what it's up to.

    On the other hand, since this obfuscation completely breaks the debugger (causing it to drop core on my machine), i can't get more details without trying to a) enter Dominus brain or b) become god. Neither seems really possible at this point.

    Kudos and ++, this is a work of art.

    jynx

    PS feel free to /msg or node me that i'm completely wrong, because i'm guessing i am...

      Says jynx:
      $z seems to just match any number of backticks (and $d is set to 2, although this doesn't need to happen) or any number of characters...
      Not exactly---$z will not match ` or `` or ``` or ```````. And it will match `xy, but not `x`y.

      The i and p substitutions are important for printing, but in the grand scheme of things they're relatively unimportant. The B, C, and S items are much more important.

      There's nothing special about %bind; it's just a regular hash. Feel free to declare it with my %bind at the top of the program. Running this under strict causes Perl to panic though; I don't know why.

      $13 and $14 correspond to the parts of $_ matched by the ($z) expressions in the ``A($z)($z) part of the pattern; similarly $17 is the $z part from `E($z).

      The really tricky part is that although it's i that sets up the $R variable for printed (as you correctly observed) there are only a few i's in $_---not nearly enough to do the job. Or so it would seem. As I said, that's the tricky part.

      Well, thanks for the kind words. :)

      $z matches 1 more \w than ': eg, >B< or >``Es`KI`B<, etc. Except for those ```S's, this generally results in a slightly shorter (different) line. Changing the 'p' handling to:
      |`i($z) (?{$R++,$q=6})|`p($z) (?{$X=$R;$R=0;$q=7}) . . . :($15, (chr 120-$X), $bind{$17}, "")[$q-6];
      will let you print (selectively) at the bottom of the loop. (or get ready to do a lot of speed-reading:) eg,      ++$xx; $q==7 and print "$xx: (", length(), ') ', substr $_,0,80;

      update: Oh yes, somes stats from the output:
      5801 substitutions longest line: 1095 chars (after 29 substitutions) first letter at: 456th sub (length 943) first word: 456 to 525 second word: 1314 to 1888 third word: 2813 to 3116 last word: 4125 to 4705 (length 71!)

      p
Re: I refuse to explain this
by Dominus (Parson) on Mar 15, 2010 at 19:21 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: obfuscated [id://70901]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (9)
As of 2014-07-24 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (158 votes), past polls