混淆难题:我们能弄清楚此Perl函数的作用吗?
时间:2020-03-06 14:24:56 来源:igfitidea点击:
sub foo {[$#{$_[!$||$|]}*@{$_[!!$_^!$_]}?@{$_[!$..!!$.]}[$_[@--@+]% @{$_[$==~/(?=)//!$`]}..$#{$_[$??!!$?:!$?]},($)?!$):!!$))..$_[$--$-]%@{ $_[$]/$]]}-(!!$++!$+)]:@{$_[!!$^^^!$^^]}]}
更新:我认为"拼图"一词暗示了这一点,但是:我知道我写的是什么。如果这个拼图对我们不感兴趣,请不要浪费任何时间。
解决方案
它需要两个arrayref并返回一个新的arrayref,其中第二个数组的内容重新排列,以使第二个部分位于第一个部分之前,并根据第一个数组的存储位置在一个点处拆分。当第二个数组为空或者包含一个项目时,仅返回第二个数组的副本。等效于以下内容:
sub foo { my ($list1, $list2) = @_; my @output; if (@$list2 > 0) { my $split = $list1 % @$list2; @output = @$list2[$split .. $#$list2, 0 .. ($split - 1)]; } else { @output = @$list2; } return \@output; }
$ list1%@ $ list2
本质上是基于$ list
来随机选择一个数组来分割数组。
原始语言主要使用许多涉及标点符号变量的重言式进行混淆。例如
!$ | | $ |
始终为1- @--@ +始终为0
更新为注意,这里的perltidy
很有帮助,但是它阻塞了!! $ ^^^!$ ^^
,将其重新格式化为!! $ ^ ^ ^!$ ^ ^
,无效Perl;应该是!! $ ^^ ^!$ ^^
。这可能是RWendi编译错误的原因。
处理其他答案时,我发现此命令很有用。
perl -MO =简明,foo,简短,紧凑的obpuz.pl> obpuz.out`
B ::简洁
这是我们弄清楚如何对该子例程进行模糊处理的方法。
很抱歉长度
首先,让我们整理代码,并添加有用的注释。
sub foo { [ ( # ($#{$_[1]}) $#{ $_[ ! ( $| | $| ) # $OUTPUT_AUTOFLUSH === $| # $| is usually 0 # ! ( $| | $| ) # ! ( 0 | 0 ) # ! ( 0 ) # 1 ] } * # @{$_[1]} @{ $_[ !!$_ ^ !$_ # !! 1 ^ ! 1 # ! 0 ^ 0 # 1 ^ 0 # 1 # !! 0 ^ ! 0 # ! 1 ^ 1 # 0 ^ 1 # 1 ] } ) ? # @{$_[1]} @{ $_[ !$. . !!$. # $INPUT_LINE_NUMBER === $. # $. starts at 1 # !$. . !!$. # ! 1 . !! 1 # 0 . ! 0 # 0 . 1 # 01 ] } [ # $_[0] $_[ # @LAST_MATCH_START - @LAST_MATCH_END # 0 @- - @+ ] % # @{$_[1]} @{ $_[ $= =~ /(?=)/ / !$` #( fix highlighting )`/ # $= is usually 60 # /(?=)/ will match, returns 1 # $` will be '' # 1 / ! '' # 1 / ! 0 # 1 / 1 # 1 ] } .. # $#{$_[1]} $#{ $_[ $? ? !!$? : !$? # $CHILD_ERROR === $? # $? ? !!$? : !$? # 0 ? !! 0 : ! 0 # 0 ? 0 : 1 # 1 # 1 ? !! 1 : ! 1 # 1 ? 1 : 0 # 1 ] } , # ( 0 ) ( $) ? !$) : !!$) # $EFFECTIVE_GROUP_ID === $) # $) ? !$) : !!$) # 0 ? ! 0 : !! 0 # 0 ? 1 : 0 # 0 # 1 ? ! 1 : !! 1 # 1 ? 0 : 1 # 0 ) .. # $_[0] $_[ $- - $- # 0 # $LAST_PAREN_MATCH = $- # 1 - 1 == 0 # 5 - 5 == 0 ] % # @{$_[1]} @{ $_[ $] / $] # $] === The version + patchlevel / 1000 of the Perl interpreter. # 1 / 1 == 1 # 5 / 5 == 1 ] } - # ( 1 ) ( !!$+ + !$+ # !! 1 + ! 1 # ! 0 + 0 # 1 + 0 # 1 ) ] : # @{$_[1]} @{ $_[ !!$^^ ^ !$^^ # !! 1 ^ ! 1 # ! 0 ^ 0 # 1 ^ 0 # 1 # !! 0 ^ ! 0 # ! 1 ^ 1 # 0 ^ 1 # 1 ] } ] }
现在,让我们删除一些混淆。
sub foo{ [ ( $#{$_[1]} * @{$_[1]} ) ? @{$_[1]}[ ( $_[0] % @{$_[1]} ) .. $#{$_[1]} , 0 .. ( $_[0] % @{$_[1]} - 1 ) ] : @{$_[1]} ] }
现在我们对发生的事情有了一些了解,让我们命名变量。
sub foo{ my( $item_0, $arr_1 ) = @_; my $len_1 = @$arr_1; [ # This essentially just checks that the length of $arr_1 is greater than 1 ( ( $len_1 -1 ) * $len_1 ) # ( ( $len_1 -1 ) * $len_1 ) # ( ( 5 -1 ) * 5 ) # 4 * 5 # 20 # 20 ? 1 : 0 == 1 # ( ( $len_1 -1 ) * $len_1 ) # ( ( 2 -1 ) * 2 ) # 1 * 2 # 2 # 2 ? 1 : 0 == 1 # ( ( $len_1 -1 ) * $len_1 ) # ( ( 1 -1 ) * 1 ) # 0 * 1 # 0 # 0 ? 1 : 0 == 0 # ( ( $len_1 -1 ) * $len_1 ) # ( ( 0 -1 ) * 0 ) # -1 * 0 # 0 # 0 ? 1 : 0 == 0 ? @{$arr_1}[ ( $item_0 % $len_1 ) .. ( $len_1 -1 ), 0 .. ( $item_0 % $len_1 - 1 ) ] : # If we get here, @$arr_1 is either empty or has only one element @$arr_1 ] }
让我们重构代码,使其更具可读性。
sub foo{ my( $item_0, $arr_1 ) = @_; my $len_1 = @$arr_1; if( $len_1 > 1 ){ return [ @{$arr_1}[ ( $item_0 % $len_1 ) .. ( $len_1 -1 ), 0 .. ( $item_0 % $len_1 - 1 ) ] ]; }elsif( $len_1 ){ return [ @$arr_1 ]; }else{ return []; } }