其实上面代码的核心就是用到了下面三个类型转换:
! 后面跟的字符会被转换成布尔值
- 后面跟的字符会被转换成数值
+[] 前面的字符会被转换成字符串
通过上面的方法,我们可以尝试做一些简单的转换:
false => ![]
true => !![]
undefined => [][[]]
NaN => +[![]]
数字
怎么用这几个符号来表示数字呢?最简单的 0 :
+[] === 0
这个很好理解,根据上面表格中的总结我们知道,蓝狮注册开户空数组转换成数字是 0,我们只需要在 [] 前面加上 + 让它转换成数字就可以得到 0 。
那么 1 可以怎么得到呢?
+!+[] === 1
因为 +[] 转换成了 0 , 0 是一个假值,那么 !+[] 就是一个真值,把一个真值转换成数字就会得到 1 ,所以我们只需要在 !+[] 前面加上 + 就可以得到 1。
那么 2 就简单了,让两个 1 相加就可以了:
!+[]+!+[] === 2
以此类推, 3456789 都可以这样表示。
如果是一个非常大的数呢?要一直相加代码就太复杂了,我们可以用另一种方法,先转换成字符串再转换成数字:
[+!+[]] === [1]
[+[]]] === [0]
[+!+[]] + [+[]]] === [1]+[0] === ’10’
+[[+!+[]]+[+[]]] === 10
这样,任意一个大数都可以表示了 …
字母
字母怎么得到呢?
首先我们尝试得到一个 undefined :
[][0] === undefined //获取一个空数组的第0个元素
[][ +[] ] === undefined //用 +[] 表示0
下面我们利用一下第三条法则: +[]前面的字符会被转换成字符串
[][+[]] +[] === ‘undefined’
这样我们就得到了 ‘undefined’ 这样一个字符串,也就是可以拿到 u n d e f i 这其中任意一个字符,比如我们要拿到字符 u :
“undefined” [ 0] === “u”
[ “undefined” ][ 0][ 0] === “u”
[ undefined +[] ][+[]][+[]] === “u”
[ [][[]] +[] ][+[]][+[]] === “u”
怎么拿到字符 a 呢,同理,我们可以从 false 里面获取:
“false”[1] === ‘a’
“false”[+!![]] === ‘a’
(false +[]) [+!![]] === ‘a’
(![] +[]) [+!![]] === ‘a’
方法
首先,我们把字符拼接起来可以得到一个方法名:
// 拿到想要的字母
“undefined”[4] // “f”
“undefined”[5] // “i”
“undefined”[6] // “n”
“undefined”[3] // “d”
// 拼接字母
“f”+”i”+”n”+”d” // “find”
然后我们通过 [] 调用方法:
[][“f”+”i”+”n”+”d”]
[][“find”]
[] .find
调用一个空数组的 find 方法有啥用呢?
没啥用 … 我们尝试把这个方法再转换成字符串:
[][“find”] +[] === “function find() { [native code] }”
太妙了,我们又有很多新的字符( a c d e f i n o t u v )可以用了 …
根据已有的字符,我们可以拼接成一个 constructor 字符串,蓝狮注册登陆也就是构造方法,当我们尝试对一些原始值读取它的 constructor 时,就可以拿到它的构造器了:
0 [“constructor”] // Number
“” [“constructor”] // String
[] [“constructor”] // Array
false [“constructor”] // Boolean
然后我们把构造器再转换成字符串:
0[“constructor”]+[] // “function Number() { … }”
我们又有了更多的新字符: m b S g B A F …
用这样的方法,我们可以先把一些关键字或表达式转换成字符串,再去获取其中的字母,就可以表示所有的字母了…
0 Comments