原文自轉->這裏javascript
早上看了justjavac大大的一篇文章:javascript 的 quine 程序升級版,瞭解了一下所謂quine程序的概念:html
一個 quine 是一個計算機程序,它不接受任何輸入,且惟一的輸出就是自身的源代碼。java
感受挺有意思的,因而打算本身用js寫一個試試。ui
首先肯定輸出方式爲控制檯,即經過console.log
輸出。code
爲有(guang)趣(gao)起見,準備從一個「打印本站域名」的「額外功能」開始:htm
console.log("perichr.org")
這個命令能夠在控制欄打印出一行perichr.org
。接下來我準備一步一步改造這個命令,直至達成quine的目標。ip
首先試着打印上面這個命令:字符串
console.log('console.log("perichr.org")')
這樣就在控制欄打印了一行console.log("perichr.org")
。注意到源碼裏外用了不一樣的引號,這是爲了規避轉義符。get
對了,別忘了須要執行本身,那麼有:源碼
console.log("perichr.org");console.log('console.log("perichr.org")')
很好,這樣即執行了「額外功能」,又打印了本身的源代……不對!壓根沒有打印本身的源代碼對吧!
從簡單的入手,不考慮打印完整源代碼,先想一想要怎樣能在執行一個功能的同時打印功能代碼呢?打印的是字符串,執行的是js源碼……想到什麼了?對了,eval
!
p='console.log("perichr.org")';eval(p);console.log(p)
很好,此次完美地打印了perichr.org
和console.log("perichr.org")
。要注意的是,這裏的變量p
沒有作聲明,嚴格模式下是通不過的喲!
不過這還遠遠不夠!來作一點小調整:
p='console.log("perichr.org");console.log(p)';eval(p)
發現了嗎?此次輸出了perichr.org
和console.log("perichr.org");console.log(p)
!進化了!接下來先討個巧,利用 賦值表達式返回右值 的小技巧來簡化一下代碼,畢竟代碼越精簡心理壓力越小嘛……
eval(p='console.log("perichr.org");console.log(p)')
接下來怎麼辦呢……來對比下上面的源碼和輸出的代碼:console.log("perichr.org");console.log(p)
,其實已經很接近了有木有!輸出碼就是缺乏了頭eval(p='
和尾')
!來,補上!
eval(p='console.log("perichr.org");console.log("eval(p=\'"+p+"\')")')
在補的時候就應該已經注意到了一個問題:轉義符!這裏已經沒法避免轉義符了!來看看輸出的代碼:eval(p='console.log("perichr.org");console.log("eval(p='"+p+"')")')
真好,已經十分接近了對吧!但仍是有一點小問題:沒錯,轉義符!輸出時源碼中的\'
被轉義成了'
!怎麼辦?那就要把文本中的'
反轉義爲\'
!怎麼轉?可使用"'".replace(/'/g,"\\'")
這種方式。考慮到文本要在p
的賦值時轉義,那麼就須要手動反轉義爲:'.replace(/\'/g,"\\\\\'")'
。接下來把它插入源碼中:
eval(p='console.log("perichr.org");console.log("eval(p=\'"+p.replace(/\'/g,"\\\\\'")+"\')")')
等等……好像有什麼不對?我剛纔是否是把一大波 有用的反斜槓 加入源代碼了?要知道,這貨也是會被轉義的啊!!怎麼辦?好嘛,來改造下反轉義代碼,這回單引號和反斜槓都要反轉義一下:.replace(/[\\']/g,"\\$&")
,這裏的$&
是指返回匹配字符串。手動反轉義:.replace(/[\\\\\']/g,"\\\\$&")
,再來一次:
eval(p='console.log("perichr.org");console.log("eval(p=\'"+p.replace(/[\\\\\']/g,"\\\\$&")+"\')")')
在控制檯試一試……成功!完美!強力!分絕不差地返回了自身!任務圓滿完成!
怎麼樣,看起來很高大上的東西,其實入門很簡單吧?
有人問,費勁心機寫這麼個東西,有啥意義?嘛,這個世界不是爲了「某些人所謂的意義」而存在的。世界存在的意義在於「世界存在」這個現象自己;我折騰這個東西的意義也就在於「折騰代碼」這件事自己。我以爲我得到了一些有意義的東西。你說呢?