Peters Family

Perl activity













Home | TIM | Perl activity





Obfuscated Perl Entries of Les Peters
















The last time I entered The Perl Journal's Obfuscated Perl Contest in 2000 (indeed, it turned out to be the last time the magazine held the contest), I won in Category 4 (The Old Standby) and Best of Show for this entry, to produce the name of the magazine, "The Perl Journal":
                  #:: ::-| ::-| .-. :||-:: 0-| .-| ::||-| .:|-. :||
                  open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('-',$1)){$q=0;for(split){s/\|
                  /:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";
                  #.: ::||-| .||-| :|||-| ::||-| ||-:: :|||-| .:|
                  

I realize that this entry is not very complicated, or even very obfuscated, but it is what it is: two lines of code that parses two lines of embedded comments in the code to read the Mayan numbers representing the individual ASCII characters that make up the magazine title, rendered in 90-degree rotated ASCII art. After the awards were announced, I looked at the other entries, and I saw that the second-place entry in this category was, in my opinion, more obfuscated in its execution than mine. I do not know exactly what the judges were looking for, and what they saw in my entry that they didn't in the other entry. Alas, I have not yet had a chance to defend this title, as the magazine stopped its print version shortly after the conclusion of the 2000 contest, and has decided for whatever reason not to revive this arcane sport of kings.

The following is a breakdown of the script.

open(Q,$0); while(<Q>){

Open itself as input, and while reading each line...

if(/^#(.*)$/){

If the current line is a comment line,

for(split('-',$1)){

Split the line, sans the sharp character, on dashes, and iterate on the results, using the default argument as the iterated value.

$q=0; for(split){

Set $q to 0, then split each value from the previous split on whitespace, again using the default argument as the iterated value.

s/\|/:.:/xg;

Substitute pipe characters for a colon, a dot, and another colon. The Mayan number 5 is represented by a horizontal bar, so in this implementation, I used a vertical bar ASCIIglyph.

s/:/../g;

Substitute colors for two dots, to transform the two-dot ASCIIglyph into two one-dot ASCIIglyphs.

$Q=$_?length:$_;

If the value of the default argument evaluates true, $Q is assigned the value of the length of the default argument; otherwise, it is assigned the value of the default argument. There is only one instance where the false leg of this ?: is taken, when the character '0' in the first comment line is reached. The Mayans used a shell-like glyph to represent a zero-filled unit, but for the purposes of this exercise, I used the ASCIIglyph '0'.

$q+=$q?$Q:$Q*20;

If the value of $q evaluates true, $q is incremented by the value of $Q; otherwise, it is incremented by the value of 20 times $Q. In the first iteration of the inner for loop, $q is always zero, so the false leg of the ?: is always taken; this will properly left shift the value by the Mayan number base of 20. On the second and final iteration of the inner loop, $q always has value, so the true leg is always taken, and the "one's digit" of the number is added into the calculation.

} print chr($q);

End of inner for loop, where we print the ASCII character of $q.

} } }

Close the outer for loop, the if statement, and the while statement.

print"\n";

Print a newline, completing the output.
















Enter supporting content here