这东西感觉挺好玩的,于是花时间研究了下
解开 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();
发现里面用到了很多知识, 总结一下.
基础
略冷
parseInt
转换进制~
按位取反(配合 indexOf
食用最佳)~~
快速取整(效率最高的方法)1e3
a in b = c + d & e
冷
with
setTimeout(string)
String.prototype.fontcolor
很冷:
fontcolor(false)
/* */
可在代码中出现的地方
a /*c*/ . /*c*/ b /*c*/ ( /*c*/ d );
了解函数逻辑之后就可以自定义修改了,
我修改了下题主的代码,下面的代码可以显示一个滚动的 "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)')//
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
@Humphry 注釋是可以去掉的,但是要留個空格替換。: