譯者:小青年
鏈接:http://www.zcfy.cc/article/1370
原文:http://jazcash.com/a-javascript-journey-with-only-six-characters/
JavaScript 是一個奇怪而有趣的語言,我們可以寫一些瘋狂卻仍然有效的代碼。它試圖幫助我們把事情轉(zhuǎn)換到基于我們?nèi)绾螌Υ麄兊奶囟愋汀?/p>
如果我們添加一個字符串州既,JavaScript 會假定我們希望為文本形式表示抱完,所以將它轉(zhuǎn)換為一個字符串。如果我們添加一個正負前綴符號剥啤,JavaScript 會假定我們希望為數(shù)值形式表示搞动。如果可能的話,對我們來說并將字符串轉(zhuǎn)換為一個數(shù)字午笛。如果我們添加一個否定符號,JavaScript 會將將字符串轉(zhuǎn)換為一個布爾值。
我們可以使用 Javascript 中[
,]
,(
,)
,!
和 +
這六個符號寫一些神奇的代碼。如果你現(xiàn)在不是在手機倒戏,你可以打開瀏覽器的控制臺,你可以將任何代碼示例粘貼到控制臺癌佩,并且代碼值為 true。
讓我們從最基本的開始便锨,要記住一些黃金規(guī)則:
-
!
后面跟的字符會被轉(zhuǎn)換成布爾值 -
+
后面跟的字符會被轉(zhuǎn)換成數(shù)值 -
[]
后面跟的字符會被轉(zhuǎn)換成字符串
來看下面的例子:
![] === false
+[] === 0
[]+[] === ""
另一件事你應(yīng)該知道的是驼卖,它可以從字符串使用方括號檢索特定的字母,像這樣:
"hello"[0] === "h"
還記得可以使多個數(shù)字號碼通過添加字符串表示在一起鸿秆,然后把整個表達式轉(zhuǎn)換成一個數(shù)字:
+("1" + "1") === 11
我們們繼續(xù)把一些東西結(jié)合在一起得到字母a
![] === false
![]+[] === "false"
+!![] === 1
------------------------
(![]+[])[+!![]] === "a" // same as "false"[1]
舉一反三酌畜!
我們可以通過true
和 false
得到相似的字母a
,e
,f
,l
,r
,s
,t
,u
,那么我們可以從其他地方得到的字母嗎卿叽?
我們可以通過一些特別的式子如[][[]]
得到undefined
桥胞,利用我們上面講到的黃金法則得到另外的字母d
,i
和 n
。
`[][[]] + [] === "undefined"`
到目前為止考婴,利用我們已經(jīng)獲得的所有字母贩虾,我們可以拼fill
, filter
和 find
。當然也有一些其他的單詞沥阱,我們也可以拼寫缎罢,但這些單詞最重要的是,他們都是數(shù)組的方法。這意味著他們是數(shù)組對象的一部分考杉,可以直接調(diào)用數(shù)組實例策精,如:[2,1].sort()
。
現(xiàn)在崇棠,了解 JavaScript 的另一件重要的特性是一個對象的屬性可以通過點符號.
或方括號[]
訪問咽袜。上述數(shù)組方法是數(shù)組對象本身的屬性,我們可以使用方括號代替點符號調(diào)用這些方法枕稀。
所以[2,1]["sort"]()
等效于 [2,1].sort()
.
我們繼續(xù)看看询刹,當我們試圖使用一個數(shù)組的方法會發(fā)生什么,我們可以使用到目前為止我們拼寫的但沒有調(diào)用的字母萎坷。
[]["fill"]
這會得到function fill() { [native code] }
凹联,我們可以把這個方法頭作為一個字符串,再次使用我們的黃金法則:
[]["fill"]+[] === "function fill() { [native code] }"
所以哆档,現(xiàn)在我們又得到其他的字符:c
,o
,v
,(
,)
,{
,[
,]
,}
蔽挠。
隨著我們新得到的c
和o
,我們現(xiàn)在可以形成constructor
這個單詞虐呻。構(gòu)造函數(shù)是一個方法象泵,所有 JS 對象僅返回自己的構(gòu)造函數(shù)。
到目前為止我們已經(jīng)處理的對象斟叼,我們可以得到它用字符串表示的構(gòu)造器函數(shù):
true["constructor"] + [] === "function Boolean() { [native code] }"
0["constructor"] + [] === "function Number() { [native code] }"
""["constructor"] + [] === "function String() { [native code] }"
[]["constructor"] + [] === "function Array() { [native code] }"
({})["constructor"] + [] === "function Object() { [native code] }"
通過這些式子偶惠,我們可以將下面的字符加入到我們的庫中:
B
,N
,S
,A
,O
,m
,b
,g
,y
,j
。
現(xiàn)在我們可以構(gòu)造一個我們可以使用方括號的函數(shù)"toString"
,我們可以這樣調(diào)用:
(10)["toString"]() === "10"
使用我們的黃金法則朗涩,我們已經(jīng)可以將任何我們想要轉(zhuǎn)換成一個字符串忽孽,但是上面這個式子怎么用呢?
好吧谢床,我告訴你兄一,Number
類型的toString
方法有一個稱為radix
(“基數(shù)”)的秘密的論點。它可以將數(shù)值在轉(zhuǎn)換為一個字符串之前先經(jīng)過基數(shù)換算识腿,像這樣:
(12)["toString"](10) === "12" // 十進制
(12)["toString"](2) === "1100" // 二進制
(12)["toString"](8) === "14" // 八進制
(12)["toString"](16) === "c" // 十六進制
但是為什么基數(shù)只寫到 16出革?最大值是 36,包括所有的字符0
-9
和 a
-z
渡讼,所以現(xiàn)在我們可以得到任何我們想要的字母數(shù)字:
(10)["toString"](36) === "a"
(35)["toString"](36) === "z"
太棒了骂束!但是其它符號如標點符號和大寫字母呢?我們接著深入探索成箫。
這取決于你的 JS 執(zhí)行時展箱,它可能會,或可能不會訪問特定的預(yù)定義的對象或數(shù)據(jù)蹬昌。如果你在瀏覽器中運行它混驰,那么你可以訪問一些存在的HTML包裝器方法。
例如皂贩,bold
是一個包裝在<>
標簽中的字符串方法栖榨。
"test"["bold"]() === "<b>test</b>"
通過這個我們得到<>
和/
兩個字符。
你可能聽說過escape
方法明刷,它主要將字符串轉(zhuǎn)換為一個 URI 友好的格式治泥,可以讓簡單的瀏覽器解釋。如果我們傳遞一個空格字符遮精,我們得到的"%20"居夹。
這里有一個工具可以自動將每個字符自動轉(zhuǎn)換。
工具地址:http://www.jsfuck.com/
源代碼地址:https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js
為什么這幾個字符有用本冲?
它不是易趣網(wǎng)做的一些不好的事情准脂,不久前允許賣家將執(zhí)行 JS 在頁面中使用只能使用這些字符,但它是一個相當罕見的攻擊向量檬洞。有些人說混淆狸膏,但事實上,有更好的方法混淆添怔。
最后湾戳,希望你會喜歡本次探秘之旅贤旷。
資源: