यह जावास्क्रिप्ट कैसे काम करता है?


93

निम्नलिखित जावास्क्रिप्ट कैसे काम करता है?

मैं समझता हूं कि यह कोडित कोड है। मैंने इसे थोड़ा कम करने की कोशिश की है, लेकिन मुझे इस बात की स्पष्ट अवधारणा नहीं मिली कि यह इस प्रभाव को कैसे प्राप्त करता है। मैं देख सकता हूं कि यह स्ट्रिंग्स का उपयोग किसी प्रकार के पुनरावृत्ति के लिए कर रहा है, दिनांक ऑब्जेक्ट का उपयोग, अजीब स्ट्रिंग हेरफेर, गणित कार्य करता है, फिर कोड स्वयं प्रिंट करता है।

एक ही प्रभाव को एक न्यूनतम उदाहरण के साथ कैसे लिखा जा सकता है?

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)')//

JSFiddle


8
शांत एनीमेशन ... कि वास्तव में कहीं का उपयोग कर समाप्त हो सकता है!
— tymeJV

7
ओह अच्छा। फ़िडल का ध्यान नहीं गया।
— ThiefMaster

37
इसे क्वीन कहा जाता है, और यह मैंने कभी देखा है और अधिक शानदार क्वीन में से एक है। en.wikipedia.org/wiki/Qoodle_(computing)
— डेविड सूपर

9
@ रोको सी। बुल्जन मुझे लगता है कि यह उनका पृष्ठ है: aem1k.com
— अलेक्जेंडर

5
लेखक की तरह लगता है अब GitHub पर एक एनोटेट संस्करण रखा गया है।
— डेर होकस्टापलर

जवाबों:


67

प्राक्कथन : मैंने http://jsfiddle.net/WZXYr/2/ पर बड़े पैमाने पर कोड को सुशोभित और एनोटेट किया

सबसे बाहरी परत पर विचार करें:

eval(z = '...');

एक कोड स्ट्रिंग चर में संग्रहीत किया जाता है z। असाइनमेंट ऑपरेटर निर्दिष्ट मान लौटाता है, इसलिए कोड स्ट्रिंग भी एक तर्क के रूप में पारित हो जाता है eval।

कोड स्ट्रिंग के zअंदर चलता है eval। सफाई होने पर भी कोड बेहद आपत्तिजनक है, लेकिन ऐसा लगता है:

  1. आधार -36 नंबरों की एक स्ट्रिंग पार्स, चरित्र द्वारा delineated 4।
  2. मूल्यों का एक नक्शा आबाद, वैश्विक चर का उपयोग कर e, xऔर yकरने के लिए पकड़ नक्शा राज्य। नक्शा स्थिति, भाग में, दीवार घड़ी पर वर्तमान दूसरी का एक कार्य है (new Date / 1e3 )।
  3. मानचित्र मानों का उपयोग करते हुए, कोड एक आउटपुट स्ट्रिंग उत्पन्न करता है, p
    • कोड का उपयोग p += " *#"[index]यह तय करने के लिए करता है कि अंतरिक्ष, तारांकन या हैश मार्क का उपयोग करना है, indexवास्तव में कहां है e[x++] + e[x++](जैसा कि ऊपर कहा गया है, eऔर xनक्शे की स्थिति के लिए जिम्मेदार हैं)
    • यदि सूचकांक की लंबाई से बड़ा है " *#", तो फॉलबैक कोड है जो आउटपुट pको वर्णों से पॉप्युलेट करता है z। इनर कैरेक्टर्स को एनिमेशन कैरेक्टर्स से पॉप्युलेट किया जाता है, जबकि बाहरी कैरेक्टर्स को खींचा जाता है z।

कोड के अंत में, एक कॉल होता है setTimeout(z), जो कोड स्ट्रिंग का अतुल्यकालिक मूल्यांकन करता है z। zकोड के लूप को यह दोहराव देता है।

सरल उदाहरण:

यहाँ एक सुपर-सरल संस्करण है ( http://jsfiddle.net/5QXn8/ ):

eval(z='p="<"+"pre>";for(i=0;i<172;++i)if(i > 62 && i < 67)p+="!---"[~~(new Date/1e2 + i)%4];else p += ("eval(z=\'" + z + "\')")[i];document.body.innerHTML = p;setTimeout(z)')
  1. forपाश कहते उत्पादन स्ट्रिंग के लिए प्रत्येक वर्ण p(स्ट्रिंग 172 वर्ण लंबा है):

    for(i=0;i<172;++i)
  2. आंतरिक स्थिति यह तय करती है कि हम 62 से 67 के बीच के चरित्र पर हैं, जो कि एनिमेटेड चरित्र हैं:

    if(i > 62 && i < 67)
  3. यदि हम हैं, तो !---दूसरी दीवार-घड़ी के मूल्य के दसवें के आधार पर, प्रिंट आउट , स्थानांतरित कर दिया गया है। यह एनीमेशन प्रभाव प्रदान करता है।

    p+="!---"[~~(new Date/1e2 + i)%4]

    (चारों ओर की सारी ख़ुशी new Dateवास्तव में सिर्फ एक तारीख मूल्य को 0 और 3 के बीच की संख्या में बदलने के लिए है)

  4. अन्यथा, यदि हम एक एनिमेटेड चरित्र पर नहीं हैं, तो इसके iद्वारा परिभाषित स्ट्रिंग से सूचकांक- चरित्र को प्रिंट करें

    "eval(z='" + z + "')"

    यही है, कोड स्ट्रिंग से zघिरा हुआ है eval('और ')।

  5. अंत में, स्ट्रिंग को आउटपुट करें और setTimeoutएक अन्य निष्पादन को पंक्तिबद्ध करने के लिए उपयोग करें z:

    document.body.innerHTML = p;setTimeout(z)

ध्यान दें कि मेरा अंतिम आउटपुट काफी सही नहीं है - मैंने बैकस्लैश के लिए अंत की ओर ध्यान नहीं दिया है - लेकिन यह अभी भी आपको एक अच्छा विचार देना चाहिए कि तकनीक आम तौर पर कैसे काम करती है।


8
इस github.com/aemkei/world/blob/master/annotated.js पर ध्यान दें - लेखक का GitHub में अपना एनोटेट संस्करण है।
— बेंजामिन ग्रुएनबाउम

36

यहाँ एनोटेट स्रोत है। Ps: मैं लेखक हूं;)

function z(){                     // will be replaced with eval

  p = "<" + "pre>";               // use <pre> tag for formatted output

  for (                           // loop though lines
    y in n = (                    // y - the line number
      "zw24"      +               // n - the encoded data
      "l6k4"      +               // every line holds encoded data
      "e3t4"      +
      "jnt4"      +               // string will be concated in build process
      "qj24"      +
      "xh2  4"    +               // data after spaces will be ignored but
      "2kty24"    +               // … is used to not break block comments
      "wrt4"      +               // … which will save some chars
      "13n24"     +
      "3n9h24"    +
      "3pdxt4"    +
      "1csb   4"  +
      "3iyb6k4"   +
      "3pk724"    +
      "3nmr24"
    ).split(4)                    // data will be split by (unused) 4

  ){
    for (                         // loop throug every char in line
      a in t = parseInt(          // numbers are encoded as string
        n[y],                     // … with a base of 36
        36
      ) + (                       // large number will be converted to string
        e =                       // e - holds the rendered globe
        x =                       // x - horizonal position
        r = []                    // r - bitmap flag if pixel is set
      )
    ){
      r = !r;                     // toggle binary flag

      for (                       // look though bitmap states
        i = 0;                 
        t[a] > i;                 // draw pixel t[a]-times
        i += .05
      )
        with (Math)               // refer to Math later
          x -= .05,
          0 > cos(                // prevent backface visibility
            o =
              new Date / 1e3 +    // get rotation based on current time
              x / PI
          ) && (
            e[                    // access matrix
              ~~(                 // convert float to integer
                sin(o) *          // rotate around y axis
                sin(.5 + y/7) *
                32                // scale up the globe
              ) + 60              // move to center
            ] = -~r               // store bitmap state in render matrix
          )
    }

    for (                         // loop through columns
      x = 0;
      122 > x;                    // break after char 122
    ) p += "   *#"[               // add space, asterisk or hash
        e[x++] +                  // … based pixel opacity
        e[x++]
      ] || (S = (                 // otherwise use the original code
        "eval(z='" +              // inception of missing "eval" statement
          z
            .split(B = "\\")      // escape \ with \\
            .join(B + B)

            .split(Q = "'")       // escape ' with \'
            .join(B + Q) +

          Q +                     // add missing ')

          ")////////"             // add extra chars to fill mapping
        )[
          x / 2 +                 // get character at current position
          61 * y-1
        ]

      ).fontcolor(                // colorize outpu
        /\w/.test(S) &&           // test for [0-9A-Z]
        "#03B"                    // render blue
                                  // otherwise pink (default)
      );

    document.body.innerHTML =     // render output
      p +=                        // append new line
      B +                         // add backspace
      "\n";                       // add new line
  }

  setTimeout(z)                   // render animation on next frame
}
z()

5
ध्यान दें, इस वीडियो में यह भी बताया गया है youtube.com/watch?v=RTxtiLp1C8Y
— बेंजामिन ग्रुएनबाउम

21

यहां एक और मैन्युअल रूप से deobfuscated संस्करण है, जो अभिव्यक्ति से बाहर सभी आरंभ को अपने बयानों में बदल रहा है:

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)';

p = "<" + "pre>";
n = ["zw2", "l6k", "e3t", "jnt", "qj2", "xh2 x/* =<,m#F^    A W###q. */", "2kty2", "wrt", "13n2", "3n9h2", "3pdxt", "1csb yz/* #K       q##H######Am */", "3iyb6k", "3pk72", "3nmr2", ""]
for (y in n) {
    e = [];
    x = 0;
    r = true;
    t = parseInt(n[y], 36) + "";
    for (a in t) {
        r = !r
        for (i = 0; i < t[a]; i += 0.05) {
             x -= 0.05;
             o = new Date / 1e3 + x / Math.PI
             if (Math.cos(o) < 0)
                 e[~~(32 * Math.sin(o) * Math.sin(0.5 + y / 7)) + 60] = -~r;
        }
    for (x = 0; x < 122;) {
        S = "eval" + "(z='" + z.split(B = "\\").join(B + B).split(Q = "'").join(B + Q) + Q + ")//m1k"
        p += "   *#"[e[x++] + e[x++]] || S[x/2+61*y-1]).fontcolor(/\w/.test(S[x/2+61*y-1]) && "#03B");
    }
    p += B + "\n";
    document.body.innerHTML = p;
}
setTimeout(z)

यहाँ होता है:

  • zकोड के सभी युक्त एक बहुस्तरीय स्ट्रिंग है। यह evalएड है।
  • कोड के अंत में, zपास किया जाता है setTimeout। यह requestAnimationFrameऔर की तरह काम करता हैeval एक साथ एक साथ, इसका मूल्यांकन उच्चतम संभव दर पर एक अंतराल में करता है।
  • कोड ही प्रारंभ करता है p, स्ट्रिंग बफर जिस पर HTML जोड़ा जाएगा, और n, बेस -36-एन्कोडेड संख्याओं की एक सरणी (द्वारा एक स्ट्रिंग में शामिल हो गया "4", टिप्पणियां अप्रासंगिक कचरा है जिसे माना नहीं जाता है parseInt)।
  • प्रत्येक संख्या nएक पंक्ति ( n.length == 16) को एनकोड करती है । यह अब प्रगणित है ।
  • चर का एक गुच्छा आरम्भिक है, कुछ को eसरणी शाब्दिक के रूप में प्रच्छन्न किया गया है, लेकिन उनका उपयोग किए जाने पर संख्या ( x) या बूलियन ( r) या स्ट्रिंग्स ( t) में डाला जाता है।
  • संख्या में प्रत्येक अंक tको उलट दिया जाता है, बूलियन को rप्रत्येक मोड़ पर लाया जाता है। विभिन्न कोणों के लिए x, और वर्तमान समय पर निर्भर करता है new Date / 1000(ताकि यह एक एनीमेशन देता है), सरणी eकुछ बिटवाइज़ ऑपरेटरों का उपयोग करके भरी 1जाती rहै - जब वह गलत है और उस समय सही है 2जब एस r।
  • तब एक लूप छवि के 61 कॉलमों को x=0दोहराता है, जो दोहरे चरणों में 122 से एकल अक्षरों को जोड़ता है p।
  • Bबैकस्लैश होने के नाते, बैकस्लैश और एपोस्ट्रोफ़्स से बचकर S, कोड को स्ट्रिंग से बनाया जाता zहै ताकि स्रोत में जो देखा जाए उसका सटीक प्रतिनिधित्व मिल सके।
  • एनिमेटेड छवि बनाने के लिए प्रत्येक दो लगातार संख्याओं eको जोड़ा जाता है और एक चरित्र तक पहुंचने के लिए उपयोग किया जाता है " *#"। यदि सूचकांकों में से एक को परिभाषित नहीं किया गया है, तो NaNसूचकांक एक अपरिभाषित चरित्र का समाधान करता है और इसके बजाय Sस्ट्रिंग से संबंधित वर्ण लिया जाता है (सूत्र की जांच करें x/2+61*y-1)। यदि वह वर्ण शब्द वर्ण होना चाहिए , तो उसे स्ट्रिंग पद्धति का उपयोग करके अलग-अलग रंग दिया जाता हैfontcolor ।
  • प्रत्येक पंक्ति के बाद, अनुगामी बैकस्पेस और एक लाइनब्रेक को जोड़ा जाता है p, और HTML स्ट्रिंग को दस्तावेज़ निकाय को सौंपा जाता है।

एक ही उदाहरण को न्यूनतम उदाहरण के लिए कैसे लिखा जा सकता है?

यहाँ एक अन्य उदाहरण है:

setInterval(z='s=("setInterval(z=\'"+\
z.replace(/[\\\\\']/g,"\\\\$&")+"\')"\
).match(/.{1,37}/g).join("\\\\\\n");d\
ocument.body.innerHTML=\"<\\pre>"+s.s\
lice(0, 175)+String( + new Date()).fo\
ntcolor("red")+s.slice(188)')

( jsfiddle.net पर डेमो )

इसमें इस तरह के एनीमेशन के लिए आवश्यक सभी प्रासंगिक चीजें हैं:

  • setInterval तथा Date एनीमेशन के लिए
  • अपने स्वयं के कोड का एक पुनर्निर्माण ( quine -like ), यहाँ में:

    s = ( "setInterval(z='" // the outer invokation
          + z.replace(/[\\\']/g,"\\$&") // the escaped version
        + "\')" ) // the end of the assignment
        .match(/.{1,37}/g).join("\\\n"); // chunked into lines
  • के माध्यम से उत्पादन document.body.innerHTMLऔर एक <pre>तत्व

  • एनिमेटेड स्ट्रिंग के साथ कोड के कुछ हिस्सों को बदलना

2
होगा, महान जवाब!
— राफेलकास्ट्रोकोटो

5

सभी कोड के साथ एक स्ट्रिंग का मूल्यांकन किया जाता है, और एक टाइमआउट लूप बनाता है; स्ट्रिंग नाम के एक चर में संग्रहीत किया जाता है zऔर कोड के बीच में, टिप्पणी के बीच /*और */एक "पृथ्वी ASCII कला" है। कोड टिप्पणियों को पार्स करता है और दस्तावेज़ की सामग्री को बदलता है, जेएस रखता है और कला को अपडेट करता है। Bellow केवल कोड कटा हुआ है:

  p="<pre>";
  for(y in n="zw24l6k4e3t4jnt4qj24xh2 x42kty24wrt413n243n9h243pdxt41csb yz43iyb6k43pk7243nmr24".split(4)){ 
    for(a in t = parseInt(n[y],36)+(e=x=r=[]))
      for(r=!r,i=0;t[a]>i;i+=.05)
        with(Math) x-= .05,0>cos(o=new Date/1e3+x/PI)&&(e[~~(32*sin(o)*sin(.5+y/7))+60] =-~ r);
          for(x=0;122>x;) p += "   *#"[e[x++]+e[x++\]] ||
              (S=("eval"+"(z=\'"+z.split(B = "\\\\").join(B+B).split(Q="\'").join(B+Q)+Q+")//m1k")[x/2+61*y-1]).fontcolor(/\\w/.test(S)&&"#\03B");
    p += B+"\\n"
    document.body.innerHTML= p
  }

6
किसी भी तरह से, अविश्वसनीय कैसे भूमध्य रेखा के आसपास ग्राफिक अधिक स्पिन है ... अद्भुत। +1 बीटीडब्लू
— रोको सी। बुल्जन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.