一步一步寫一個簡單的js版quine程序

原文自轉->這裏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.orgconsole.log("perichr.org")。要注意的是,這裏的變量p沒有作聲明,嚴格模式下是通不過的喲!

不過這還遠遠不夠!來作一點小調整:

p='console.log("perichr.org");console.log(p)';eval(p)

發現了嗎?此次輸出了perichr.orgconsole.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,"\\\\$&")+"\')")')

在控制檯試一試……成功!完美!強力!分絕不差地返回了自身!任務圓滿完成!

怎麼樣,看起來很高大上的東西,其實入門很簡單吧?

有人問,費勁心機寫這麼個東西,有啥意義?嘛,這個世界不是爲了「某些人所謂的意義」而存在的。世界存在的意義在於「世界存在」這個現象自己;我折騰這個東西的意義也就在於「折騰代碼」這件事自己。我以爲我得到了一些有意義的東西。你說呢?

相關文章
相關標籤/搜索