Obfuscation Puzzle: Können Sie herausfinden, was diese Perl-Funktion tut? [geschlossen]

StackOverflow https://stackoverflow.com/questions/100106

  •  01-07-2019
  •  | 
  •  

Frage

sub foo {[$#{$_[!$||$|]}*@{$_[!!$_^!$_]}?@{$_[!$..!!$.]}[$_[@--@+]%
@{$_[$==~/(?=)//!$`]}..$#{$_[$??!!$?:!$?]},($)?!$):!!$))..$_[$--$-]%@{
$_[$]/$]]}-(!!$++!$+)]:@{$_[!!$^^^!$^^]}]}

Update: Ich dachte, das Wort "Puzzle" dies bedeuten würde, aber: I wissen, was sie tut - ich schrieb es. Wenn das Puzzle, das Sie nicht interessiert, bitte vergeuden Sie keine Zeit auf sie.

War es hilfreich?

Lösung

Hier ist, wie Sie herausfinden, wie diese Unterroutine de-verschleiern.

Sorry für die Länge

Lassen Sie uns zunächst den Code aufzuräumen und nützliche Kommentare hinzufügen.

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
      ]
    }
  ]
}

Lassen Sie uns jetzt einen Teil der Verschleierung entfernen.

sub foo{
  [
    (
      $#{$_[1]} * @{$_[1]}
    )

    ?

    @{$_[1]}[
      ( $_[0] % @{$_[1]} ) .. $#{$_[1]}

      ,

      0 .. ( $_[0] % @{$_[1]} - 1 )
    ]

    :

    @{$_[1]}
  ]
}

Nun, da wir eine Vorstellung davon, was los ist, wollen wir die Variablen nennen.

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
  ]
}

Lassen Sie uns den Code Refactoring, um es ein wenig besser lesbar zu machen.

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 [];
  }
}

Andere Tipps

ich dieser Befehl hilfreich, wenn auf meiner anderen Antwort zu arbeiten.

perl -MO=Concise,foo,-terse,-compact obpuz.pl > obpuz.out

B :: Concise

Es dauert zwei arrayrefs und gibt einen neuen ArrayRef mit dem Inhalt der zweiten Anordnung solcher neu angeordnet, dass der zweite Teil kommt, bevor der erste Teil, Split an einem Punkt auf dem Speicherplatz der ersten Anordnung basiert. Wenn das zweite Array leer ist oder ein Element enthält, gibt nur eine Kopie des zweiten Feldes. Entspricht der folgenden:

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 nimmt im Wesentlichen eine zufällige Stelle des Arrays aufgeteilt, basierend auf $list, die auf die Speicheradresse von $ Liste auswertet, wenn sie in einem numerischen Kontext bewertet.

Das Original verwendet meist eine Menge Tautologien Interpunktion unter Einbeziehung von Variablen zu verschleiern. z.

  • !$| | $| ist immer 1
  • @- - @+ ist immer 0

Aktualisiert dass perltidy sehr hilfreich war zu beachten, hier zu entziffern, aber es erstickte an !!$^^^!$^^, die es !!$^ ^ ^ !$^ ^ umformatiert, die ungültig Perl ist; es sollte !!$^^ ^ !$^^ werden. Dies könnte die Ursache für RWendi der Kompilierung-Fehler sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top