此代码输出D
。问题是如何?
alert([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[+!+[]]](+[]+[+[]])[+!+[]]);
我了解![]
评估为false
或0
等等,但它是如何执行的?我怎样才能将其转换为人类可以理解的东西,而不仅仅是Jon Skeet?
有人可以打破这部分代码并向我解释发生了什么吗?
答案 0 :(得分:11)
好吧,在部分中评估表达式,最后它相当于:
[]['sort']['call']()["btoa"]("00")[1]; // "D"
可以简化为:
btoa("00")[1]; // "D"
如何“解码”?
只需检查所使用的运算符,例如,我们首先可以看到使用了数组文字,然后完成了几个<em>括号表示法属性访问,以及几次调用。
它是如何运作的?
诀窍是链接多个类型的转换,例如,获取f
字母:
(![]+[])[+[]]
如果我们检查第一部分,在括号中![]+[]
,我们会看到一个布尔否定,它将返回false
,因为数组对象总是真实的,然后是连接
生成字符串"false"
,然后,第二部分,我们看到应用于该字符串的括号,用于访问字符,以及表达式+[]
,这导致0
+[]
给出零,因为数组的toString
方法返回一个空字符串,对于一个像这样的空数组,空字符串在转换为数字时生成为零(一元{{这个例子中有1}}运算符。)
只有这样的技巧,产生字符串的东西,例如+
,"true"
,"false"
,"null"
等......还有更多技巧可以获得在数字上。
例如,为了获得一个数字 - 访问一个字符,他们再次使用神秘的类型转换:
"undefined"
答案 1 :(得分:4)
它通过javascript类型转换做了一些技巧。 CMS指出,它相当于:[]['sort']['call']()["btoa"]("00")[1];
他们通过将这些字符串从false
等等中删除来构建字符串。
例如,要使s
进入“排序”:
获取“false”:(![]+[])
- ![]
返回false,+[]
将其转换为字符串。
获取值3:!+[]+!+[]+!+[]
- 每个!+[]
返回true
,但是当您添加布尔值时,您将获得整数表示。例如true + true = 2
使用字符串索引访问表示法s
获取"false"[3] = 's'
:(![]+[]) [!+[]+!+[]+!+[]]
现在你有一个s
。他们一直这样做,直到他们有足够的权限来访问他们想要的任何方法或属性。
答案 2 :(得分:1)
![]是假的。 ![] + []评估为'false'。 +[]
为0所以!+ []为真,等等。对于隐含的类型转换,javascript非常奇怪