2010-02-23 57 views
7

這段代碼如何工作?這個混淆的Perl代碼是如何工作的?

#!/usr/bin/perl 

$i=4;$|[email protected]=map{("!"x$i++)."K$_^\x{0e}"} 
"BQI!\\","BQI\\","BQI","BQ","B","";push 
@f,[email protected][1..5];@f=map{join"",undef, 
map{chr(ord()-1)}split""}@f;{;[email protected] 
f;print$f;[email protected],$f;select undef,undef, 
undef,.25;redo;last;exit;print or die;} 
+2

什麼問題,除了在極端醜陋? – anthares

+0

可執行的線條噪音:-D – Krab

+0

神奇的Perl精靈使這一切發生。 – Ether

回答

8

沒有什麼神奇怎麼回事,只是混淆。我們來看一個高層次的觀點。首先要注意的事情是,後來,在字符串中的每個字符作爲好像它是一個字符解釋:前人物的

[1] map{chr(ord()-1)} ... 

因此,像「6qD」的字符串會導致「5rC」( 6','q'和'D')。感興趣的主要點是一個字符串的起點附近的數組:

[2] ">>>E!)",">>>E)",">>>E",">>>",">>",">","" 

此定義的「面具」,我們將取代以後,這個字符串的序列:

[3] "9$_*\x{0e}" 

他們會插入$_點。字符串\x{0e}代表一個十六進制控制字符;請注意,\x{0d},就在它之前的字符是回車符。這就是當我們做[1]時會被代入[3]。

在組裝[3]字符串之前,我們在[2]中的每個元素前面添加一個等於i的!。每個連續的元素比之前的元素多獲得一個!。請注意,其值在!之前的字符是空格

腳本遍歷每個組裝的數組元素的,現在看起來更像這樣的其餘部分:

[4] "!!!!!9>>>E!)\x{0e}", ---> "  8===D (" 
    "!!!!!!9>>>E)\x{0e}", ---> "  8===D(" 
    "!!!!!!!9>>>E\x{0e}", ---> "  8===D" 
    "!!!!!!!!9>>>\x{0e}", ---> "  8===" 
    "!!!!!!!!!9>>\x{0e}", ---> "   8==" 
    "!!!!!!!!!!9>\x{0e}", ---> "   8=" 
    "!!!!!!!!!!!9\x{0e}", ---> "   8" 

然後reverse操作會將在反向相同的元件,創建一個循環。

在這一點上,你應該能夠看到產生動畫的模式emerge。現在只需要移動動畫中的每一步,然後再返回,這由腳本的其餘部分完成。每步的時間延遲由選擇語句決定:

[5] select undef, undef, undef, 0.25 

它告訴我們在每次迭代之間等待250毫秒。如果你想看到它加速或減速,你可以改變它。

+0

我用大致相同的代碼替換了原始源代碼,這對於工作是安全的。只是讓你知道,如果你可能想修改你的答案。 –

16

讓我們首先把這個通過perltidy

$i = 5; 
$| = @f = map { ("!" x $i++) . "9$_*\x{0e}" } ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", ""; 
push @f, reverse @f[ 1..5 ]; 
@f = map { 
    join "", 
     map { chr(ord() - 1) } 
     split // 
} @f; 
{ 
    $f = shift @f; 
    print $f; 
    push @f, $f; 
    select undef, undef, undef, .25; 
    redo; 
    last; 
    exit; 
    print or die; 
} 

第一行是顯而易見的。

第二行列出了一個列表">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "",並將它們全部等長並添加星號和「Shift Out」(回車後的字符)。

第三行將項目5到1(按該順序)追加到該列表中,因此它將是">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", ">", ">>", ">>>", ">>>E"

該地圖將所有字符減1,從而創建像8===D()這樣的元素。

第二個循環只是每0.25秒在一個循環中打印列表中的元素。回車導致它們相互覆蓋,以便看到動畫。最後幾行是從來沒有達到過的,因此是假的。

+0

我用大致相同的代碼替換了原始源代碼,這對工作是安全的。只是讓你知道,如果你可能想修改你的答案。 –

14

來自該文件的數據被加載到名爲Perl解釋器的程序中。解釋器解析代碼並將其轉換爲一系列「操作碼」 - 一種字節碼語言,它在Perl代碼和運行代碼的機器語言之間有一半的距離。如果轉換過程中沒有錯誤(稱爲「編譯」),則代碼由Perl解釋器的另一部分執行。在執行過程中,程序可能會改變機器的各種狀態,如分配,釋放,讀取和寫入存儲器,或使用系統的輸入/輸出和其他功能。

(CW - 更多的鐵桿黑客比我歡迎糾正任何錯誤或誤解,並添加更多的信息)

+3

大聲笑。自從我看到一個痛苦的文字阿比蓋爾式的答案已經很長時間了。 –

+2

+1 Stack Overflow的單數最大答案eva! – Sampson