Nous (David, Stéphane, Kai et BooK) étions à YAPC::Europe 2000 à Londres... et nous y avons donné des lightning talk (5 minutes, chrono).
Voici le talk de BooK, concernant l'obfuscation...
This is YAPC::Europe, this is Perl. You know there is more than one way to do it. Well, there is also more than one way to obfuscate it.
There are several reasons why people volontarily obfuscate their code to the extreme:
There are several ways to obfuscate your code:
The next question you will ask is "what to code?" --that is, besides a convoluted print statement (read JAPH).
The use of formal constraints takes some freedom away from you. But it actually frees you too:
So now you can ask: which constraints to use?
Apart from the natural production constraints which are "fast, cheap, reliable: choose any 2", possible constraints are:
Now it's the hands-on session, with the hand out.
This is a P(ython|erl) script commented in P(erl|ython):
###################################################################### # Python # Perl # ###################################################################### q = -1 ; #=; $n = int rand 1001; print '? '; q# import whrandom ; i = 1 #; while(<>){ q# n = whrandom.randint(0,1000) #; $i++; q# while q != n : #; last if $_ == $n; q# q = int(raw_input('? ')) #; print 'Too '; q# if q == n : #; print ($_<$n?'big':'small'); q# break #; print "\n? "; q# print 'Too', #; } q# if q < n : #; print "You won in $i tries\n"; q; print 'big' # else: # print 'small' # i = i + 1 # print 'You won in', i, 'tries' #;
This might prove interesting for beginners in either of the two languages. Which you can also interpret as my personnal way to try and make Perlists and Pythonists friends again... :-)
And this is a random suck-o-meter in interlaced P(erl|ython), but the Python version is a little more extreme.
q = 0 #=;sub randint{$A=(pop,pop)[int rand 2]};@ A = ('Perl', 'Python', q) #));sub A{$_}; import whrandom; s = tr = 0 #= ;$ _ = "Perlon'"; y = 'really' #=" tychoon= if(rand 2)%2; m = x =s | tr / 2197 #no'/ Perl comment \b / if !/y/; print A[whrandom.randint(0,1)], if x == whrandom.randint(0,1)+q: #:; tr = 1 ; qq = '' # =;if((rand 2)%2){ print y,"sucks",qq #,||"sucks"}else{ eval q>>.q# else: #,; print "rules"; q = 1 #=}print"\n"
/;{}def/#{def}def/$_={/Times-Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$ ;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup 260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverse q(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" " !! !! % !" !" ! ! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %T charpath clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " ! #! ##} pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} pop neg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop " { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/;@ARGV=(@ARGV[-14..-1])x50;q} 0 "%};s/m[ou]|[-\dA-ln-z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$# %2?'':"$0;").'pop;')x(ord($1)-31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print ; sub showpage {}
This program has a lot to tell. Though Perl and PostScript are very different in appearance (one if infixed, the other postfixed, one works with lists, the other with dictionaries...), in this case they performed quite hand in hand. I must add that PostScript is very well suited for obfuscation even for novices, thanks to the def operator.
If you look closer at the output of these two programs, you will notice that the highlighted part, the one that is missing in the output of the Perl program, is exactly (your screen/eyes/printer resolution may vary) the one that is printed by the PostScript file. Isn't this come complementarity?
$A++
contest printoutCheck $A++
.