No one yet? OK, here's it is:
Separate the lines of code:
****************
Line 1 creates an array containing 24 elements.
@a = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23);
****************
Line 2 uses the special variable $: which happens to contain " n-", reverses it and sets $b equal the first character. This is the same as:
$b = '-';
****************
Line 3 is equivalent to:
$a = '$b=3';
****************
Line 4 is puzzling. I think I know how it works, but not sure why. First thing is to group it according to operator precedence:
$c = ord ($; + $[ - 2 + (ord $b)) ;
(ord $b) equals 45
$[ is another special variable, default value is zero
$; is another special variable, equal to the string " 43" - (that's a single ASCII character octal 043)
Substituting:
$c = ord ( " 43" + 0 - 2 + 45 );
For some reason I do not understand, the " 43" character is evaluated as zero. I think. So we get:
$c = ord ( 0 + 0 - 2 + 45 );
$c = ord ( 43 );
Ord wants a string, so the number 43 is converted to the string "43", then ord returns the numeric ASCII value of '4', which is 52.
$c = ord '43';
$c = 52 ;
****************
Line 5 is easy. See line 2, and substitute.
$b = ord '-';
$b = 45;
****************
Line 6 is also easy. Take the string in $a, split it into a list of single characters, and take the numeric ASCII value of the first element (which happens to be the character '$').
$a = ord ('$');
$a = 36
****************
Line 7 is even easier. Add one to the special variable $[, which is zero.
$d = 1;
****************
Line 8 has another special variable. Good thing I have a perl book by O'Reilly:
$b = 31 - ord $; ;
$b = 31 - 28;
$b = 3;
****************
Line 9. Tricky use of the q//
$e = ( ord "@" ) - ord ";" ;
$e = 64 - 59
$e = 5
****************
Line 10. Here's the other line that puzzles me. First, add some spaces so it makes sense:
$f = 1 + ( length (@a) * 3 );
I know this evaluates to 7. Not sure why length(@a) is equal to 2. Maybe perl uses a 16 bit number as an array reference and the length function counts these bytes. Dunno.
$f = 7;
****************
Line 11. Now that I know $f, this line is easy:
$g = $f + ($d * 2);
$g = 9;
****************
Line 12. Takes the number of elements in @a divides by two and adds 1:
$h = 1 + ( 24 / 2 )
$h = 13
****************
So far, all the program has done is the following:
@a=(0..23);
$a=36;
$b=3;
$c=52;
$d=1;
$e=5;
$f=7;
$g=9;
$h=13;
****************
Line 13: A 24 element array is defined. This is the encrypted message.
****************
Line 14:
14a. @b = map {
14b. s!([a-h])!$$1!gi;
14c. 1 while (
14d. s!(-?$[a-h])(-?$[a-h])!$1+$2!gi
14e. );
14f. $_ = eval;
14g. } @c;
This takes the encrypted message in @c, which is an array of 24 strings containing the letters a-f in various combinations, and some punctuation. Turns it into an array of numbers.
14b inserts a "$" in front of every letter ( deg becomes $d$e$g )
14d adds the '+' character ( $d$e$g becomes $d+$e+$g )
14f evaluates the expression. ($d+$e+$g becomes 1+5+9 which equals 15 )
****************
15. The message is almost decoded. So finish decoding it and print. Heres the line with whitespace added for readability.
print map{ chr( $_ + 80 + shift @b ) } @a;
Not hard to figure that one out. For each element in @a, $_ is loaded with that element, then the following expression is evaluated:
chr( $_ + 80 + shift @b )
The result of the map function is an array, and is passed to the print command.
This line has the same end result:
for ( $n = 0; $n < 24; $n++) {
print chr( $a[$n] + 80 + $b[$n] );
}
****************
Thanks Cal, that was fun to figure out. Learned alot about using ord and map.
If you've read this far, you'll like
The Fifth Annual Obfuscated Perl Contest Winners . Unfortunately, the original site is no more, but the pages are still cached on Google.
[ March 28, 2001: Message edited by: el84 ]