4 个回答

@Humphry 注釋是可以去掉的,但是要留個空格替換。:

eval(z='p="<"+"pre>"/*                 */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/*                     */42kty24wrt413n243n\
9h243pdxt41csb yz/*                       */43iyb6k43pk7243nm\
r24".split(4)){/*                           */for(a in t=pars\
eInt(n[y],36)+/*                             */(e=x=r=[]))for\
(r=!r,i=0;t[a/*                               */]>i;i+=.05)wi\
th(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.spl\
it(B = "\\\\")./*                           */join(B+B).split\
(Q="\'").join(B+Q/*                       */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*                    */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//

这东西感觉挺好玩的,于是花时间研究了下

代码分解

解开 eval, 函数结构如下

z="...";
function main(){

    p = "<" + "pre>";

    for (y in n = "zw24l6k4e3t4jnt4qj24xh2 x/* =<,m#F^    A W###q. */42kty24wrt413n243n9h243pdxt41csb yz/* #K       q##H######Am */43iyb6k43pk7243nmr24".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");
        document.body.innerHTML = p += B + "\\n";
    }
    
    setTimeout(main);
}
main();

整理缩进,变量替换...过程略...最终结果:

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-= /*        a##KWR#### W[            */.05,0>cos(o=\
new Date/1e3/*      .Q##1111111Md#.###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)';
    
const EARTH_WIDTH = 32;
const LINE_COLUMN = 61;
const RESOLUTION = .05;

function main() {

    //"<pre>...." 会被浏览器解析为 "<pre>...</pre>"
    p = "<pre>";

    //地球数据
    // n = [
         //->parseInt 36    //t             //r
         "zw2",             //46514         [    ******     *    ]
         "l6k",             //27452         [  *******    *****  ]
         "e3t",             //18281         [ ********  ******** ]
         "jnt",             //25481         [  *****    ******** ]
         "qj2",             //34382         [   ****   ********  ]
         "xh2",             //43382         [    ***   ********  ]
         "2kty2",           //4331162       [    ***   * ******  ]
         "wrt",             //42473         [    **    *******   ]
         "13n2",            //51374         [     *   *******    ]
         "3n9h2",           //6124214       [      *  ****  *    ]
         "3pdxt",           //6223313       [      **  ***   *   ]
         "1csb",            //63227         [      ***  **       ]
         "3iyb6k",          //213232412     [  *   **   **    *  ]
         "3pk72",           //6231422       [      **   *    **  ]
         "3nmr2",           //6141422       [      *    *    **  ]
         ""];               //NaN           [                    ]
    

    // y  => row
    for (row = 0; row < n.length; row++) {
        
        let t = parseInt(n[row], 36).toString();
        // e => EarthRowChar
        let earthRow = [];
        let r = true;
        let x = 0;
        
        // for (a in t = parseInt(n[y], 36) + (e = x = r = [])) {
        for (a of t) {

            //[4,6,5,1,4] => 一行地球字符的组成: 4 * 海洋 + 6 * 陆地 + 5 * 海洋 ...
            r = !r;

            for (var i = 0; i < a; i += RESOLUTION) {

                x -= RESOLUTION;

                let time = new Date() / 1000;

                let rotate = time + x / Math.PI;

                // 判断此时的 x 位置在正面还是背面
                let isFrontFace = Math.cos(rotate) < 0;

                if (isFrontFace) {

                    //row  = [0..13]
                    //0.5 + row  / 7 = [.5 .. 2.5]
                    //模拟近似的球面, 沿经度线的半切面形状
                    let latitude = 0.5 + row / 7; 

                    // [...,28,,92...]
                    // ~~ 是两次按位取反,常用用于快速取整
                    // 
                    let index = ~~(EARTH_WIDTH * Math.sin(rotate) * Math.sin(latitude)) + 60;

                    // 确定是陆地还是海洋
                    earthRow[index] = r ? 2 : 1;
                }
            }
        }

        // x => col 此处的 x 与外部的 x 互不影响,故可以替换变量名
        // for (x = 0; x < 61; x++) {
        for (var col = 0; col < LINE_COLUMN; col++) {
            // 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");

            //2 < e[x] + e[x+1] < 4
            //确定陆地,海洋和边界各用什么字符来表示
            let earthStr = "   *#"[earthRow[col * 2] + earthRow[col * 2 + 1]];
            
            let escapedCodeZ = z.replace(/\\/g, String.raw`\\`).replace(/'/g, String.raw`\'`);

            let codeChar = ("eval(z='" + escapedCodeZ + "')//m1k")[col + LINE_COLUMN * row];

            //模拟代码高亮  .fontcolor(false) 显示的字体颜色为紫色
            let colorCodeChar = codeChar.fontcolor(/\w/.test(codeChar) && "#03B");

            p += earthStr || colorCodeChar;
        }
        p += "\\\n";
    }
    
    document.body.innerHTML = p;
    
    setTimeout(main);
}    

main();

发现里面用到了很多知识, 总结一下.

总结:

基础

  • 类型转换规则
  • eval 字符串脱逸

略冷

  • parseInt 转换进制
  • ~ 按位取反(配合 indexOf 食用最佳)
  • ~~ 快速取整(效率最高的方法)
  • 科学计数法 1e3
  • 运算符号优先级规则 a in b = c + d & e

  • 使用 with
  • setTimeout(string)
  • String.prototype.fontcolor

很冷:

  • fontcolor(false)
  • /* */ 可在代码中出现的地方

    • a /*c*/ . /*c*/ b /*c*/ ( /*c*/ d );
  • 利用浏览器补全 html 代码

分解 + 组合 = 创造

了解函数逻辑之后就可以自定义修改了,
我修改了下题主的代码,下面的代码可以显示一个滚动的 "SF"

eval(z ='p="<"+"pre>"/*                 */;for(y in n=".849b8\
9xfb85hqrpb85cdukb /*                     */8202b282la7281592\
83rpz284b0et_19wy/*                        */819wyk8qmib8uagb\
8dbb8.8.".split(/*                          */8)){for(a in t=\
parseInt(n[y],/*                             */36)+(e=x=r=[])\
)for(r=!r,i=0/*                               */;t[a]>i;i+=.0\
5)with(Math)/*                                 */x-=.05,0>cos\
(o=new Date /*               SF                *//1e3+x/PI)&&\
(e[~~(32*sin/*                                 */(o)*sin(.5+y\
/7))+60]=-~r)/*                                */;for(x=0;122\
>x;)p+="  *#"/*                               */[e[x++]+e[x++\
]-1]||( S = ( /*                             */"eval"+"(z= \'\
"+z.split(B =  /*                           */"\\\\").join(B+\
B).split(Q="\'")./*                       */join(B+Q)+Q+")/")\
[x/2+61*y-1])["font"+/*               */"color"](/\\w/.test(S\
)&&"#03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')

向 @justjavac 大神致敬,向 sf 社区致敬:

eval(z='p="<"+"pre>"/*                 */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/*                     */42kty24wrt413n243n\
9h243pdxt41csb yz/*                       */43iyb6k43pk7243nm\
r24".split(4)){/*      SSSS     FFFFFFFF    */for(a in t=pars\
eInt(n[y],36)+/*     SSS  SSS   FF           */(e=x=r=[]))for\
(r=!r,i=0;t[a/*     SS          FF            */]>i;i+=.05)wi\
th(Math)x-= /*      SSS         FF             */.05,0>cos(o=\
new Date/1e3/*       SSSSSS     FFFFFFFF       */+x/PI)&&(e[~\
~(32*sin(o)*/*            SSS   FF             */sin(.5+y/7))\
+60] =-~ r);/*             SS   FF             */for(x=0;122>\
x;)p+="   *#"/*     SSS  SSS    FF            */[e[x++]+e[x++\
]]||(S=("eval"/*      SSSS      FF           */+"(z=\'"+z.spl\
it(B = "\\\\")./*                           */join(B+B).split\
(Q="\'").join(B+Q/*                       */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*                    */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题