这段Perl代码是如何混淆的?

7
这段代码是如何工作的呢?
#!/usr/bin/perl

$i=4;$|=@f=map{("!"x$i++)."K$_^\x{0e}"}
"BQI!\\","BQI\\","BQI","BQ","B","";push
@f,reverse@f[1..5];@f=map{join"",undef,
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;}

2
除了极其丑陋之外,还有什么问题吗? - anthares
1
我不知道为什么,但我觉得这真的很有趣。不仅是那个NSFW动画,还有似乎合理的涉及其工作原理的问题。 - Chris Farmer
3
显然这是一个遗传算法。 - Paul
3
我修改了原始内容,现在它适合在工作场所查看。 - Brad Gilbert
3
我感到受骗了,因为现在它是SFW。 - Sean Hayden
显示剩余4条评论
3个回答

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"

该映射将所有字符递减一,从而创建像8===D ()这样的元素。

第二个循环简单地以0.25秒的间隔循环打印列表中的元素。 回车使它们相互覆盖,从而看到动画效果。 最后几行永远不会被执行,因此是无效的。


我用大致等效的代码替换了原始源代码,这样就可以安全地使用了。只是提醒您,以防您需要修改您的答案。 - Brad Gilbert

14

数据从文件中加载到一个名为Perl解释器的程序中。解释器解析代码并将其转换为一系列"操作码"--一种介于Perl代码和机器语言之间的字节码语言。如果转换过程(称为"编译")没有错误,那么该代码将由Perl解释器的另一部分执行。在执行期间,程序可以改变机器的各种状态,如分配、取消分配、读写内存或使用系统的输入/输出和其他功能。

(CW-比我更有经验的黑客可以纠正任何错误或误解,并添加更多信息)


3
LOL。我已经很久没有看到像阿比盖尔那样过于字面的回答了。 - Michael Carman

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]中的每个元素之前添加! 数量相等的感叹号。每个连续元素比前一个元素多一个!。请注意,值刚好在!之前的字符是空格
脚本的其余部分遍历了每个已组装的数组元素,它们现在看起来更像这样:
[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操作将相同的元素反向添加,创建一个循环。

此时,您应该能够看到产生动画的模式。现在只需要通过动画中的每个步骤并返回,这可以通过脚本的其余部分完成。每个步骤的时间步延迟由选择语句控制:

[5] select undef, undef, undef, 0.25

这告诉我们在每次迭代之间等待250毫秒。如果您想加快或减慢速度,可以更改此设置。


我用大致等效的代码替换了原始源代码,这样就可以安全地使用了。只是提醒您,以防您需要修改您的答案。 - Brad Gilbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接