views:

1692

answers:

3

How does this code work at all?

#!/usr/bin/perl

$i=4;$|=@f=map{("!"x$i++)."K$_^\x{0e}"}
"BQI!\\","BQI\\","BQI","BQ","B","";push
@f,reverse@f[1..5];@f=map{join"",undef,
map{chr(ord()-1)}split""}@f;{;$f=shift@
f;print$f;push@f,$f;select undef,undef,
undef,.25;redo;last;exit;print or die;}
+7  A: 

There's no magic going on here, just obfuscation. Let's take a high-level view. The first thing to notice is that later on, every character in strings is interpreted as if it were the previous character:

[1] map{chr(ord()-1)} ...

Thus, a string like "6qD" will result in "5rC" (the characters before '6', 'q', and 'D', respectively). The main point of interest is the array of strings near the beginning:

[2] ">>>E!)",">>>E)",">>>E",">>>",">>",">",""

This defines a sequence of "masks" that we will substitute later on, into this string:

[3] "9$_*\x{0e}"

They'll get inserted at the $_ point. The string \x{0e} represents a hex control character; notice that \x{0d}, the character just before it, is a carriage return. That's what'll get substituted into [3] when we do [1].

Before the [3] string is assembled, we prepend a number of ! equal to i to each element in [2]. Each successive element gets one more ! than the element before it. Notice that the character whose value is just before ! is a space .

The rest of the script iterates over each of the assembled array elements, which now look more like this:

[4] "!!!!!9>>>E!)\x{0e}",  ---> "     8===D ("
    "!!!!!!9>>>E)\x{0e}",  ---> "      8===D("
    "!!!!!!!9>>>E\x{0e}",  ---> "       8===D"
    "!!!!!!!!9>>>\x{0e}",  ---> "        8==="
    "!!!!!!!!!9>>\x{0e}",  ---> "         8=="
    "!!!!!!!!!!9>\x{0e}",  ---> "          8="
    "!!!!!!!!!!!9\x{0e}",  ---> "           8"

Then the reverse operation appends the same elements in reverse, creating a loop.

At this point you should be able to see the pattern emerge that produces the animation. Now it's just a matter of moving through each step in the animation and back again, which is accomplished by the rest of the script. The timestep delay of each step is governed by the select statement:

[5] select undef, undef, undef, 0.25

which tells us to wait 250 milliseconds between each iteration. You can change this if you want to see it speed up or slow down.

John Feminella
I replaced the original source with roughly equivalent code, that is safe for work. Just letting you know in case you might want to modify your answer.
Brad Gilbert
+15  A: 

Lets first put this through perltidy

$i = 5;
$| = @f = map { ("!" x $i++) . "9$_*\x{0e}" } ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "";
push @f, reverse @f[ 1..5 ];
@f = map {
    join "",
      map { chr(ord() - 1) }
      split //
} @f;
{
    $f = shift @f;
    print $f;
    push @f, $f;
    select undef, undef, undef, .25;
    redo;
    last;
    exit;
    print or die;
}

The first line is obvious.

The second line makes a list ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", and spaces them all to be equally long and appends an asterisk and a 'Shift Out' (the character after a carriage return).

The third line appends items 5 to 1 (in that order) to that list, , so it will be ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", ">", ">>", ">>>", ">>>E".

The map decrements the all characters by one, thus creating elements like 8===D ().

The second loop simply prints the elements in the list in a loop every 0.25 seconds. The carriage return causes them to overwrite each other, so that an animation is seen. The last couple of lines are never reached and thus bogus.

Leon Timmermans
I replaced the original source with roughly equivalent code, that is safe for work. Just letting you know in case you might want to modify your answer.
Brad Gilbert
+12  A: 

Data from the file is loaded into a program called a Perl interpreter. The interpreter parses the code and converts it to a series of "opcodes" -- a bytecode language that is sort of halfway between Perl code and the machine language that the code is running on. If there were no errors in the conversion process (called "compiling"), then the code is executed by another part of the Perl interpreter. During execution, the program may change various states of the machine, such as allocating, deallocating, reading, and writing to memory, or using the input/output and other features of the system.

(CW - More hardcore hackers than I are welcome to correct any errors or misconceptions and to add more information)

mobrule
LOL. It's been a long time since I've seen an painfully literal Abigail-esque answer.
Michael Carman
+1 The single-greatest answer on Stack Overflow eva!
Jonathan Sampson