為我的部落格做了一個很有 geek 風格的關於頁面。
運行下面 javascript 代碼,可以看到我的資訊。
(+[[]+(1<<1<<1<<1)+(1^1<<1)+(1<<1>>1)+(-~1<<1<<1)+(1.1>>1.1)+(11>>>1)])[[(!!/-/+{})[111^111]+[[]+{}][!1&.1][1|1>>1|1]]+([111/[]+[]][+(1>1)][([]+{})[11-1>>1]+[[],[]+{}+[]][[]+1][1]+(/^/[1]+[])[1|1>>1|1]+[{},1e1,!{}+[]][1+1][1<<1^1]+(11/!{}+{})[~1+1e1+~1]+[!!{}+{}][[]&111][1&1]+(/^/[111]+[])[11^11]+[{},[{}]+{},1][1+[]][11-~1+11>>1]+(!!1+{})[1&1>>1]+([]+{1:1}+[])[1|1]+[[]+!!1][111>>>111][1<<1>>1]]+[])[([]+![111])[1|1<<1|1]+[/=/,[]+[][11]][1|[]][1>>1]+([{}]+{})[1+!![1]]+[1,!1+/~/][1%11][1^1<<1]+(111/[]+{})[~1+1e1+~1]+[!!/-/+/-/][111%111][+!!1]]((~1+1e1+1)+((!1&.1)==([]+/-/[(!![111]+{})[1^1]+(!![1]+[])[1<<1^1]+(!{}+{})[1^1<<1]+(!![1]+/-/)[+(1>1)]])[+(1>1)]),1-~1<<1)](~1-~1e1<<1<<1)+":"+(([]===[])+/-/)[5]+(([]===[])+/-/)[5]+(+[[]+(1e1>>1)+(~1+1e1+~1)+(!1&.1)+(111%11)+(1+1<<1)+(1<<1^11>>1)+(1<<1<<1)+(~1+1e1+1)+(+(1>1))+(+[])+(~1-1+11)+(-~1<<1<<1)+(1-~1<<1)+(~1+1e1)])[[(!!/-/+[])[11&[]]+[[]+{11:11}+[]][111>>111][1+[]]]+([11/!1+/1/][1&1>>1][([{}]+{})[1e1>>1|1]+[[],[]+{111:111}+[]][1|1][111%11]+([]+[][11])[1<<1>>1]+[{},1e1,!/~/+{}][1<<1^1>>1][1<<1^1]+([]+11/!{})[~1+1e1+~1]+[!![111]+[]][1%1][1&1]+([]+[][111])[.1^!1]+[{},[]+{},1][111%11][11-~1+11>>1]+([]+!!1)[111>>>111]+([]+{}+[])[[]+1]+[!!1+[]][1^1][111%11]]+[])[(!1+{})[1^1<<1]+[/=/,[]+/^/[11]][1|[]][11.11>>11.11]+([]+{}+[])[~~(1.1+1.1)]+[1,!{}+/~/][1][1|1<<1]+(1/!{}+[])[~1+1e1+~1]+[!![1]+{}][111.111>>111.111][1+[]]]((11^1<<1)+((1>>1)==([]+/-/[(!!/-/+/-/)[+(111>111)]+(!![11]+[])[1-~1]+(![11]+{})[1|1<<1|1]+(!!{}+[])[11%11]])[111.111>>111.111]),11+1>>1)](~1-~1e1<<1<<1)+"."+(+[[]+([]+1)+(1-~1<<1)+(1+1<<1)+(1|1<<1)+(1<<1<<1<<1)])[[(!!1+{})[!1&.1]+[[]+{}+[]][1&[]][1+[]]]+([11/[]+{}][+(111>111)][([{}]+[{}])[1e1>>1]+[[],[]+{}][[]+1][+!!1]+(/^/[111]+/&/)[1&1]+[{},1e1,!1+[]][1<<1][1^1<<1]+(111/!{}+/1/)[~1+1e1+~1]+[!!/-/+[]][11>>11][1|1]+([][1]+/&/)[1.1>>1.1]+[{},[{}]+{},1][~~1][1+1e1+1]+([]+!!1)[1^1]+([]+{})[1&1]+[!!1+{}][!1&.1][1|[]]]+[])[([]+!1)[1|1<<1|1]+[/=/,[]+/^/[11]][111%11][11.11>>11.11]+([{}]+[{}])[~~(1.1+1.1)]+[1,[]+!/~/][1|1>>1|1][1^1<<1]+([]+11/[])[11+1>>1]+[!!/-/+{}][+(1<1)][~~1]]((1e1-1)+((+[])==([]+/-/[(!!1+[])[!1&.1]+(!!/-/+/-/)[1|1<<1|1]+(!1+{})[1<<1^1]+(!![1]+/-/)[11>>11]])[111^111]),-~11>>1)](~1-~1e1<<1<<1)
如何?的呢?
@OKter 說是 ASCII 碼拼接。到底是不是呢?
第一步
先來個簡單的,就以 justjavac
為例吧。首先我們要輸出 j
。
下面這段代碼可以輸出 j
:
(1+{})[4]
解釋:代碼 1+{}
的結果是 "1[object
Object]"
, 顯然,我們得到了一個包含 j 的字串。但為什麼會如此奇怪呢?畢竟我們都期望 1+{}
的結果應該是 1。
對象加法
有下面這樣的一個加法操作。
value1 + value2
在計算這個運算式時,內部的操作步驟是這樣的 (§11.6.1):
將兩個運算元轉換為原始值 (以下是數學標記法的虛擬碼,不是可以啟動並執行 JavaScript 代碼):
prim1 := ToPrimitive(value1) prim2 := ToPrimitive(value2)
PreferredType
被省略,因此 Date
類型的值採用 String
,其他類型的值採用 Number
。
如果 prim1 或者 prim2 中的任意一個為字串,則將另外一個也轉換成字串,然後返回兩個字串串連操作後的結果。
否則,將 prim1 和 prim2 都轉換為數字類型,返回他們的和。
更多詳細內容參考
由於字串可以當作數組一樣取裡面的元素,於是 (1+{})[4]
就得到了 j。
第二步
既然我們得到了 j,那下一步就是 u 了。我們還是按照這個思路,哪個字串裡面還有 u 呢? 在 javascript 中確實有這麼一個特殊的值,含有 u: "undefined",思來想去,可以使用這段代碼:
/1/[1]+[]
分開解釋:
/1/
是一個正在運算式
當他後面跟上 [] 時,被強制轉換成了數組,然後去取裡面的元素(第二個元素),得到的結果是 undefined(注意:是 undefined 值,不是字串)
把 undefined 轉換成字串,在這裡我們把它和數組相加。
呵呵,上面使用正在運算式 /1/
有點兒賣弄的嫌疑,其實用 1[1]
就夠了。
為了更有 geek 感,可以多出現 0 和 1。通過 /1+/[+0]+[+1]
我們可以得到字串 "undefined1"。
使用數組操作符把我們想要的 u 提取出來, (/1+/[+0]+[+1])[0]
。
現在我們已經得到了字串 "ju" 了。按照這種方法,我們可以得到其他的字串。沒有做不到的,只有想不到的。
問題來了
用這種方法能拼出所有的字元嗎? @長夜 則提出了更深的問題: “可以拼中文嗎?”
@TODO 待續……
大功告成
當我們得到了所有的字串,就可以使用 + 號把他們串連起來。 你以為這就完了嗎?當然遠遠沒有,我們應該讓我們的代碼更 Cool,更有 geek 範。
相關閱讀:
- JavaScript 的怪癖 1:隱式類型轉換
- 為什麼 ++[[]][+[]]+[+[]] = 10?