This is a read-only archive!

One-liner explained

Someone asked for an explanation of my obfuscation, so here goes:

The -l flag to Perl makes it stick a newline on the end of output. Handy.

Reformatted and indented, the code would be

for(0..0xb271a1){
    ++( $} ||= q|A|)
}
( $; = q;"\x70\x72\x69\x6e\x74\x24\x7d"; ) =~ s;.*;$&;eee

A good obfuscation technique is to use odd characters as delimiters; Perl lets you get away with nearly any character to delimit the q// and s/// operators etc. Replacing those with (), it looks much easier to understand:

for(0..0xb271a1){
    ++( $} ||= q(A) )
}
( $; = q("\x70\x72\x69\x6e\x74\x24\x7d") ) =~ s(.*)($&)eee

Perl also lets you use some fairly odd variable names. I use $} and $;. Some of these kinds of names are reserved for various builtin functionality in Perl. $| would've made my obfu much harder to read, but that variable is taken by Perl.

The for loop counts from 0 to 11694497 (written as hex 0xb271a1, for no reason other than to add line noise).

The single line inside the loop initializes the variable $}. ||= assigns a value "A" to $} only if $} has no value; equivalent to

$} = $} || "A";

The ||= is redundant and does essentially nothing 11694496 out of 11694497 iterations through the loop. But the variable $} itself is returned each time. This is so you can chain assignments, etc. in normal programming use. I use this to do a $}++.

++ on a string in Perl will do some magic. "A"++ = "B". Eventually, "Z"++ = "AA", and "ZZ"++ = "AAA". This is a handy obfuscated method of creating words, which I saw once a while back on PerlMonks. After 11694497 iterations, $} will hold the text "YOINK".

Another variable with an odd name, $;, is given the value '"\x70\x72\x69\x6e\x74\x24\x7d"'. Note the double-quotes are part of its value. This is just an encoding of the string '"print$}"'. I do a regex substitution on it, replacing .* with $&. $& is a builtin variable that holds the value of everything that matched, in this case, the entire string. I put three e flags on the end of the substitution; this causes whatever is in the right side of the s/// to be evaluated as though you called eval on it three times.

Why three of them? Well, the first one does nothing. Evaluating a string just returns the string. It's as though you put a line like this in a script:

'"\x70\x72\x69\x6e\x74\x24\x7d"';

which returns the value

"\x70\x72\x69\x6e\x74\x24\x7d"

Note that " is still part of the result at this point. The second eval evaluates the result of the previous eval; seeing a string surrounded by double-quotes, it will process the string, interpolating the \x codes. Without the double-quotes, it would try to execute those \x's as Perl commands, which give all kinds of parser errors. The above string processing results in:

print$}

The third eval evaluates that string, which actually runs the command, i.e. it prints the value of $}, "YOINK".

November 30, 2006 @ 4:41 AM PST
Cateogory: Programming
Tags: Perl

1 Comment

boniek
Quoth boniek on November 30, 2006 @ 10:21 AM PST

Thank you for taking time to write this explanation. I learned a few tricks from it ;)