Wie funktioniert das folgende JavaScript?
Ich verstehe, dass es sich um minimierten Code handelt. Ich habe versucht, es ein wenig zu verschleiern, aber ich kann mir kein klares Konzept darüber machen, wie es diesen Effekt erzielt. Ich kann sehen, dass es Strings für irgendeine Art von Iteration, Verwendung des Date-Objekts, seltsame String-Manipulation, Math-Funktionen verwendet, dann druckt sich der Code selbst.
Wie könnte der gleiche Effekt mit einem minimalen Beispiel umgeschrieben werden?
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
Alexander
quelle
quelle
Antworten:
Vorwort : Ich habe den Code unter http://jsfiddle.net/WZXYr/2/ ausführlich verschönert und kommentiert.
Betrachten Sie die äußerste Schicht:
In der Variablen wird eine Codezeichenfolge gespeichert
z
. Der Zuweisungsoperator gibt den zugewiesenen Wert zurück, sodass die Codezeichenfolge auch als Argument übergeben wirdeval
.Die Codezeichenfolge wird
z
innerhalb von ausgeführteval
. Der Code ist extrem stumpf, selbst wenn er bereinigt wird, aber es scheint:4
.e
,x
undy
zu halten Karte Zustand. Der Kartenstatus ist teilweise eine Funktion der aktuellen Sekunde auf der Wanduhr (new Date / 1e3
).p
p += " *#"[index]
, um zu entscheiden, ob ein Leerzeichen, ein Sternchen oder eine Raute verwendet werden soll, woindex
sich tatsächlich befindete[x++] + e[x++]
(wie oben erwähnte
undx
für den Kartenstatus verantwortlich)." *#"
, gibt es einen Fallback-Code, der die Ausgabep
mit Zeichen von fülltz
. Innere Zeichen werden mit Animationszeichen gefüllt, während äußere Zeichen aus gezogen werdenz
.Am Ende des Codes gibt es einen Aufruf von
setTimeout(z)
, der die Codezeichenfolge asynchron auswertetz
. Dieser wiederholte Aufruf vonz
ermöglicht dem Code eine Schleife.Einfaches Beispiel:
Hier ist eine supereinfache Version ( http://jsfiddle.net/5QXn8/ ):
Die
for
Schleife fügt jedes Zeichen zur Ausgabezeichenfolge hinzup
(die Zeichenfolge ist 172 Zeichen lang):Die innere Bedingung entscheidet, ob wir uns auf einem Charakter zwischen Position 62 und 67 befinden. Dies sind die animierten Charaktere:
Wenn dies der Fall ist, wird der Ausdruck
!---
basierend auf dem Zehntel des zweiten Wanduhrwerts verschoben. Dies liefert den Animationseffekt.(Die ganze Gemeinheit
new Date
ist wirklich nur da, um einen Datumswert in eine Zahl zwischen 0 und 3 umzuwandeln.)Wenn Sie kein animiertes Zeichen verwenden, drucken Sie das Indexzeichen
i
aus der durch definierten ZeichenfolgeDas heißt, die Codezeichenfolge,
z
die voneval('
und umgeben ist')
.Geben Sie abschließend die Zeichenfolge aus und stellen Sie
setTimeout
eine weitere Ausführung vonz
:Beachten Sie, dass meine endgültige Ausgabe nicht ganz richtig ist - ich habe die Backslashes gegen Ende nicht berücksichtigt -, aber es sollte Ihnen trotzdem eine ziemlich gute Vorstellung davon geben, wie die Technik im Allgemeinen funktioniert.
quelle
Hier ist die kommentierte Quelle. Ps: Ich bin der Autor;)
quelle
Hier ist eine weitere manuell deobfuscierte Version, die alle Initialisierungen aus dem Ausdruck in eigene Anweisungen verschiebt:
Folgendes passiert:
z
ist eine mehrzeilige Zeichenfolge, die den gesamten Code enthält. Es isteval
ed.z
wird an übergebensetTimeout
. Es funktioniert wierequestAnimationFrame
undeval
zusammen und wertet es in einem Intervall mit der höchstmöglichen Rate aus.p
, der Zeichenfolgenpuffer, an den der HTML- Code angehängt wird, undn
ein Array von Base-36-codierten Zahlen (verbunden durch eine Zeichenfolge"4"
, wobei die Kommentare irrelevanter Müll sind, der von nicht berücksichtigt wirdparseInt
).n
codiert eine Zeile (n.length == 16
). Es ist jetzt aufgezählt .e
Array-Literal getarnt, aber sie werden dann bei Verwendung in Zahlen (x
) oder Boolesche Werte (r
) oder Zeichenfolgen (t
) umgewandelt.t
wird aufgezählt, wobei der Boolesche Wert inr
jeder Runde invertiert wird . Für verschiedene Winkelx
und abhängig von der aktuellen Zeitnew Date / 1000
(so dass eine Animation angezeigte
wird ) wird das Array mit einigen bitweisen Operatoren gefüllt - mit1
wannr
ist falsch und2
s wannr
ist zu diesem Zeitpunkt wahr.x=0
in doppelten Schritten von bis 122, wobei einzelne Zeichen an angehängt werdenp
.B
Als Backslash wird die ZeichenfolgeS
aus der Code-Zeichenfolge erstellt,z
indem Backslashes und Apostrophe ausgeblendet werden, um eine genaue Darstellung des Erscheinungsbilds in der Quelle zu erhalten.e
werden hinzugefügt und verwendet, um auf ein Zeichen von zuzugreifen" *#"
und das animierte Bild aufzubauen. Wenn einer der Indizes nicht definiert ist, wird derNaN
Index in ein undefiniertes Zeichen aufgelöst und stattdessen wird das entsprechende Zeichen aus derS
Zeichenfolge übernommen (siehe Formelx/2+61*y-1
). Wenn dieses Zeichen ein Wortzeichen sein soll , wird es mit derfontcolor
String-Methode unterschiedlich gefärbt .p
, und die HTML-Zeichenfolge wird dem Dokumentkörper zugewiesen.Hier ist ein anderes Beispiel:
( Demo bei jsfiddle.net )
Es hat alle relevanten Dinge, die Sie für diese Art von Animation benötigen:
setInterval
undDate
für die AnimationEine Rekonstruktion des eigenen Codes ( quine- like) hier:
Die Ausgabe über
document.body.innerHTML
und ein<pre>
Elementquelle
Eine Zeichenfolge mit dem gesamten Code wird ausgewertet, und eine Zeitüberschreitung führt zu einer Schleife. Die Zeichenfolge wird in einer Variablen mit dem Namen
z
und in der Mitte des Codes zwischen Kommentaren gespeichert ,/*
und*/
es befindet sich eine "Earth ASCII Art". Der Code analysiert die Kommentare und ändert den Dokumentinhalt, behält das js bei und aktualisiert die Grafik. Unten ist nur der Code in Scheiben geschnitten:quelle