Comment fonctionne le JavaScript suivant?
Je comprends que c'est du code minifié. J'ai essayé de le désobscurcir un peu, mais je ne parviens pas à comprendre clairement comment il produit cet effet. Je peux voir qu'il utilise des chaînes pour une itération quelconque, l'utilisation de l'objet Date, une manipulation de chaîne étrange, des fonctions mathématiques, puis le code s'imprime.
Comment le même effet pourrait-il être réécrit avec un exemple minimal?
eval(z='p="<"+"pre>"/* ,.oq#+ ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^ A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/* p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/* d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /* aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/* .Q#########Md#.###OP A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* , (W#####Xx######.P^ T % */sin(.5+y/7))\
+60] =-~ r);/* #y `^TqW####P###BP */for(x=0;122>\
x;)p+=" *#"/* b. OQ####x#K */[e[x++]+e[x++\
]]||(S=("eval"/* l `X#####D , */+"(z=\'"+z.spl\
it(B = "\\\\")./* G####B" # */join(B+B).split\
(Q="\'").join(B+Q/* VQBP` */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/* TP */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//
javascript
Alexandre
la source
la source
Réponses:
Avant - propos : j'ai beaucoup embelli et annoté le code sur http://jsfiddle.net/WZXYr/2/
Considérez la couche la plus externe:
Une chaîne de code est stockée dans la variable
z
. L'opérateur d'affectation renvoie la valeur affectée, de sorte que la chaîne de code est également transmise en tant qu'argument danseval
.La chaîne de code
z
s'exécute à l'intérieur deeval
. Le code est extrêmement obtus, même lorsqu'il est nettoyé, mais il semble:4
.e
,x
ety
de tenir l' état de la carte. L'état de la carte est en partie fonction de la seconde actuelle sur l'horloge murale (new Date / 1e3
).p
p += " *#"[index]
pour décider s'il faut utiliser un espace, un astérisque ou une marque de hachage, oùindex
est réellemente[x++] + e[x++]
(comme indiqué ci-dessus,e
etx
sont responsables de l'état de la carte)" *#"
, il existe un code de secours qui remplit la sortiep
avec les caractères dez
. Les personnages internes sont remplis de personnages d'animation, tandis que les caractères externes sont extraitsz
.À la fin du code, il y a un appel à
setTimeout(z)
, qui évalue de manière asynchrone la chaîne de codez
. Cet appel répété dez
permet au code de faire une boucle.Exemple simple:
Voici une version super simple ( http://jsfiddle.net/5QXn8/ ):
La
for
boucle ajoute chaque caractère à la chaîne de sortiep
(la chaîne est longue de 172 caractères):Le conditionnel interne décide si nous sommes sur un personnage entre la position 62 à 67, qui sont les personnages animés:
Si c'est le cas, imprimez
!---
, décalé en fonction du dixième de la deuxième valeur d'horloge murale. Cela fournit l'effet d'animation.(Toute la méchanceté autour
new Date
est vraiment là pour transformer une valeur de date en un nombre compris entre 0 et 3.)Sinon, si nous ne sommes pas sur un caractère animé, alors imprimez le
i
caractère d' index à partir de la chaîne définie parAutrement dit, la chaîne de code
z
entourée pareval('
et')
.Enfin, sortez la chaîne et utilisez
setTimeout
pour mettre en file d'attente une autre exécution dez
:Notez que ma sortie finale n'est pas tout à fait correcte - je n'ai pas pris en compte les contre-obliques vers la fin - mais cela devrait tout de même vous donner une assez bonne idée du fonctionnement général de la technique.
la source
Voici la source annotée. Ps: je suis l'auteur;)
la source
Voici une autre version désobfusquée manuellement, déplaçant toute initialisation de l'expression dans ses propres instructions:
Voici ce qui se passe:
z
est une chaîne multiligne contenant tout le code. C'esteval
éd.z
est passé àsetTimeout
. Cela fonctionne commerequestAnimationFrame
eteval
ensemble, en l'évaluant dans un intervalle au taux le plus élevé possible.p
, le tampon de chaîne auquel le HTML sera ajouté etn
un tableau de nombres encodés en base 36 (joints en une chaîne par"4"
, les commentaires étant des déchets non pertinents qui ne sont pas pris en compte parparseInt
).n
encode une ligne (n.length == 16
). Il est maintenant énuméré .e
littéral de tableau mais elles sont ensuite converties en nombres (x
) ou booléens (r
) ou en chaînes (t
) lorsqu'ils sont utilisés.t
est énuméré, inversant le booléen àr
chaque tour. Pour différents anglesx
, et en fonction de l' heure actuellenew Date / 1000
(de sorte qu'il donne une animation), le tableaue
est rempli à l'aide de quelques opérateurs au niveau du bit - avec1
quandr
est faux et2
s quandr
est vrai à ce moment.x=0
à 122 par étapes doubles, en ajoutant des caractères simples àp
.B
étant la barre oblique inverse, la chaîneS
est construite à partir de la chaîne de codez
en échappant les barres obliques inverses et les apostrophes, pour obtenir une représentation précise de ce à quoi elle ressemblait dans la source.e
sont ajoutés et utilisés pour accéder à un personnage de" *#"
, pour construire l'image animée. Si l'un des indices n'est pas défini, l'NaN
index se résout en un caractère indéfini et à la place le caractère respectif de laS
chaîne est pris (consultez la formulex/2+61*y-1
). Si ce caractère doit être un caractère de mot , il est coloré différemment à l'aide de lafontcolor
méthode String .p
et la chaîne HTML est affectée au corps du document.Voici un autre exemple:
( démo sur jsfiddle.net )
Il contient tout ce dont vous avez besoin pour ce type d'animation:
setInterval
etDate
pour l'animationUne reconstruction de son propre code (à la quine ), ici:
La sortie via
document.body.innerHTML
et un<pre>
élémentla source
Une chaîne avec tout le code est évaluée et un délai d'expiration fait la boucle; La chaîne est stockée dans une variable nommée
z
et au milieu du code, entre les commentaires/*
et*/
il y a un "Earth ASCII Art". Le code analyse les commentaires et modifie le contenu du document, en conservant les js et en mettant à jour l'art. Ci-dessous est juste le code tranché:la source