2010-02-23 2 views
7

Comment ce code fonctionne-t-il?Comment fonctionne ce code Perl obfusqué?

#!/usr/bin/perl 

$i=4;$|[email protected]=map{("!"x$i++)."K$_^\x{0e}"} 
"BQI!\\","BQI\\","BQI","BQ","B","";push 
@f,[email protected][1..5];@f=map{join"",undef, 
map{chr(ord()-1)}split""}@f;{;[email protected] 
f;print$f;[email protected],$f;select undef,undef, 
undef,.25;redo;last;exit;print or die;} 
+2

Quel est le problème, sauf extrême laideur? – anthares

+0

Bruit de ligne exécutable :-D – Krab

+0

Les fées magiques Perl rendent tout cela possible. – Ether

Répondre

8

Il n'y a pas de magie ici, juste une obfuscation. Prenons une vue de haut niveau. La première chose à noter est que plus tard, tous les caractères dans les chaînes est interprété comme si elle était le caractère précédent:

[1] map{chr(ord()-1)} ... 

Ainsi, une chaîne comme « 6qD » se traduira par « 5rC » (les caractères avant ' 6 ',' q 'et' D ', respectivement). Le principal point d'intérêt est le tableau de chaînes vers le début:

[2] ">>>E!)",">>>E)",">>>E",">>>",">>",">","" 

Cela définit une séquence de « masques » que nous allons remplacer plus tard, dans cette chaîne:

[3] "9$_*\x{0e}" 

Ils vont être inséré au point $_. La chaîne \x{0e} représente un caractère de contrôle hexadécimal; Notez que \x{0d}, le caractère juste avant, est un retour chariot. C'est ce qui va être substitué dans [3] quand nous faisons [1].

Avant que la chaîne [3] ne soit assemblée, nous ajoutons un nombre de ! égal à i pour chaque élément de [2]. Chaque élément successif obtient ! de plus que l'élément précédent. Notez que le caractère dont la valeur est juste avant ! est un espace .

Le reste du script itère sur chacun des éléments du tableau assemblés, qui ressemblent maintenant plus comme ceci:

[4] "!!!!!9>>>E!)\x{0e}", ---> "  8===D (" 
    "!!!!!!9>>>E)\x{0e}", ---> "  8===D(" 
    "!!!!!!!9>>>E\x{0e}", ---> "  8===D" 
    "!!!!!!!!9>>>\x{0e}", ---> "  8===" 
    "!!!!!!!!!9>>\x{0e}", ---> "   8==" 
    "!!!!!!!!!!9>\x{0e}", ---> "   8=" 
    "!!!!!!!!!!!9\x{0e}", ---> "   8" 

Ensuite, l'opération reverse les mêmes éléments ajoute à l'inverse, la création d'une boucle.

À ce stade, vous devriez être en mesure de voir le motif qui émerge et qui produit l'animation. Maintenant, il suffit de passer à travers chaque étape de l'animation et de revenir, ce qui est accompli par le reste du script. Le retard de timestep de chaque étape est régie par l'instruction select:

[5] select undef, undef, undef, 0.25 

qui nous dit d'attendre 250 millisecondes entre chaque itération. Vous pouvez changer cela si vous voulez le voir accélérer ou ralentir.

+0

J'ai remplacé la source d'origine par un code à peu près équivalent, ce qui est sans danger pour le travail. Juste vous faire savoir au cas où vous pourriez vouloir modifier votre réponse. –

16

Lets d'abord mettre cela par perltidy

$i = 5; 
$| = @f = map { ("!" x $i++) . "9$_*\x{0e}" } ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", ""; 
push @f, reverse @f[ 1..5 ]; 
@f = map { 
    join "", 
     map { chr(ord() - 1) } 
     split // 
} @f; 
{ 
    $f = shift @f; 
    print $f; 
    push @f, $f; 
    select undef, undef, undef, .25; 
    redo; 
    last; 
    exit; 
    print or die; 
} 

La première ligne est évidente.

La deuxième ligne fait une liste ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", et les espace tous pour être tout aussi long et ajoute un astérisque et un «Shift Out» (le caractère après un retour chariot).

La troisième ligne ajoute les éléments 5 à 1 (dans cet ordre) à cette liste, ce sera donc ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", ">", ">>", ">>>", ">>>E".

La carte décrémente tous les caractères de un, créant ainsi des éléments tels que 8===D().

La deuxième boucle imprime simplement les éléments de la liste dans une boucle toutes les 0,25 secondes. Le retour chariot les oblige à se remplacer mutuellement, de sorte qu'une animation est vue.Les deux dernières lignes ne sont jamais atteintes et donc fausses.

+0

J'ai remplacé la source d'origine par du code à peu près équivalent, ce qui est sans danger pour le travail. Juste vous faire savoir au cas où vous pourriez vouloir modifier votre réponse. –

14

Les données du fichier sont chargées dans un programme appelé interpréteur Perl. L'interpréteur analyse le code et le convertit en une série de "opcodes" - un langage de bytecode qui est en quelque sorte à mi-chemin entre le code Perl et le langage machine sur lequel s'exécute le code. S'il n'y avait pas d'erreurs dans le processus de conversion (appelé "compilation"), le code est exécuté par une autre partie de l'interpréteur Perl. Au cours de l'exécution, le programme peut modifier divers états de la machine, tels que l'allocation, la désallocation, la lecture et l'écriture en mémoire, ou l'utilisation des entrées/sorties et d'autres fonctions du système.

(CW - Plus pirates hardcore que je ne hésitez pas à corriger les erreurs ou les idées fausses et d'ajouter plus d'informations)

+3

LOL. Il y a longtemps que j'ai vu une réponse douloureusement littérale Abigail-esque. –

+2

+1 La meilleure réponse sur Stack Overflow eva! – Sampson