2010-02-23 50 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