in reply to The Decline and Fall of the Roman Empire
I like your obfu very much, because it's very difficult to read despite that it uses only very few selected obfu techniques.
Here's some SPOILER
First, let's reformat the obfu by normalizing spaces and newlines, and omitting a few commas and parentheses that are clearly not needed:
END { print " \n" } sub I { $_ } sub II { -shift } sub III { chr shift } sub IV { $_[ 0 ] + $_[ 1 ] } sub V { IV(0, 1) } sub VI { IV(V, II(V)) } sub VII { IV(V, V) } sub VIII { IV(V, II(shift)) } sub IX { $_[ VI ]**VII } sub X { IX(VII) } sub XI { IV(VII, V) } sub XII { IX(IX(XI)) } sub XIII { IV(X, V) } sub XIV { IV(IX(X), II(XI)) } sub XV { (XIV, @_) } sub XVI { $_[ VI ] ** XI } sub XVII { IX(XVI(VII)) } sub XVIII { IV(XVI(VII), II(V)) } sub XIX { IV(XVI(VII), VII) } sub XX { $_[ VI ] * $_[ V ] } my $XVI = IV(XX(VII, XVIII), II(XIV)); for( IV(XVII, IX(XI)), IV(IX(XVIII), VIII(XVIII)), II(VII), V, II(IV(XVII, XX(VII, XIX))), XX(XIV, XIII), XV(V, XIII, VIII(XIV), II(XI)), XV(II(IV(V, XII)), XX(XI, IX(X)), XX(XI, XVIII)), XV( VIII(XVIII), IV(XIII, II(XII)), XX(X, XX(VII, IX(XI))), II(XVIII), VII, XVI(VII), IV(VII, XVI(II(VII))) ), XV(II(IV(XIII, XX(XIII, XIV)))) ) { $XVI += I and print III $XVI } __END__
Now we get rid of those roman identifiers which are a pain to read. (Update: I accidentally copied the above version of the code again here, now here's the correct version.)
END { print " \n" } sub b { $_ } sub c { -shift } sub d { chr shift } sub e { $_[ 0 ] + $_[ 1 ] } sub f { e(0, 1) } sub g { e(f, c(f)) } sub h { e(f, f) } sub i { e(f, c(shift)) } sub j { $_[ g ]**h } sub k { j(h) } sub l { e(h, f) } sub n { j(j(l)) } sub o { e(k, f) } sub p { e(j(k), c(l)) } sub r { (p, @_) } sub t { $_[ g ] ** l } sub u { j(t(h)) } sub v { e(t(h), c(f)) } sub w { e(t(h), h) } sub z { $_[ g ] * $_[ f ] } my $t = e(z(h, v), c(p)); for( e(u, j(l)), e(j(v), i(v)), c(h), f, c(e(u, z(h, w))), z(p, o), r(f, o, i(p), c(l)), r(c(e(f, n)), z(l, j(k)), z(l, v)), r( i(v), e(o, c(n)), z(k, z(h, j(l))), c(v), h, t(h), e(h, t(c(h))) ), r(c(e(o, z(o, p)))) ) { $t += b and print d $t } __END__
Now we can inline the subroutines and do arithmetic constant folding. It is easy, because every part of the code calls only subroutines above, and every subroutine is very simple, so you can inline them in one simple pass. (That's theory. In practice, I've made lots of mistakes when trying. Note that you can't write -f instead of -(f), as -f is a filetest.)
(Update: gsubed "chr" to "ord" in comment)END { print " \n" } sub b { $_ } sub c { -shift } sub d { chr shift } sub e { $_[ 0 ] + $_[ 1 ] } sub f { 1 } sub g { 0 } sub h { 2 } sub i { 1 - shift() } sub j { shift()**2 } sub k { 4 } sub l { 3 } sub n { 81 } sub o { 5 } sub p { 13 } sub r { 13, @_ } # 13 = ord('r') - ord('e') = ord('n') - ord('a') sub t { shift()**3 } sub u { 64 } sub v { 7 } sub w { 10 } sub z { shift() * shift() } my $t = 1; for( 73, 43, -2, 1, -84, 65, r(1, 5, -12, -3), r(-82, 48, 21), r(-6, -76, 72, -7, 2, 8, -6), r(-70) ) { $t += $_ and print chr $t } __END__
Finally, we inline the r() calls too, and remove the subroutines as they are not used anymore. I also remove the and, as $t += $_ is always true.
END { print " \n" } my $t = 1; for( 73, 43, -2, 1, -84, 65, 13, 1, 5, -12, -3, 13, -82, 48, 21, 13, -6, -76, 72, -7, 2, 8, -6, 13, -70 ) { print chr ($t += $_); } __END__
|
|---|