Deparsing/Decompose — пошаговое описание этого запутанного Perl-скрипта

Как заголовок - пожалуйста, кто-нибудь может объяснить, как работают следующие скрипты

это напечатает текст: "Perl ребята умные"

''=~('(?{'.('])@@^{'^'-[).*[').'"'.('-[)@{:__({:)[{(-:)^}'^'}>[,[]*&[[[[>[[@[[*_').',$/})')

это печатает только "b"

use strict;
use warnings;
''=~('(?{'.('_/).+{'^'/]@@_[').'"'.('=^'^'_|').',$/})')

perl -MO=Deparse показывает только это:

use warnings;
use strict 'refs';
'' =~ m[(?{print "b",$/})];

но не знаю почему... ;(

Каков рекомендуемый способ декомпозиции подобных скриптов? Как начать?

так, попробовал это:

'' =~
(
        '(?{'
        .
        (
                '])@@^{' ^ '-[).*['
        )
        .
        '"'
        .
        (
                 '-[)@{:__({:)[{(-:)^}' ^ '}>[,[]*&[[[[>[[@[[*_'
        )
        .
        ',$/})'
)

несколько частей объединены .. И результат побитового ^, вероятно, дает части текста. В:

perl -e "print '-[)@{:__({:)[{(-:)^}' ^ '}>[,[]*&[[[[>[[@[[*_'"

печатает "Perl ребята умные" и первый ^ генерирует "print".

Но когда я переписываю его на:

'' =~
(
    '(?{'
    .
    (
        'print'
    )
    .
    '"'
    .
    (
         'Perl guys are smart'
    )
    .
    ',$/})'
)

Мой перл сказал мне:

panic: top_env

Странно, первый раз вижу такое сообщение об ошибке...

Это значит: нельзя заменять 'str1' ^ 'str2' на result (не понимаю почему) и почему perl печатает паническое сообщение?

мой перл:

This is perl 5, version 12, subversion 4 (v5.12.4) built for darwin-multi-2level

Ps: примеры генерируются здесь


person cajwine    schedule 16.06.2012    source источник
comment
Изучение Perl — очевидный ответ.   -  person Oliver Charlesworth    schedule 16.06.2012
comment
Но на самом деле никто не должен писать такой код, поэтому нет причин его понимать.   -  person Oliver Charlesworth    schedule 16.06.2012
comment
Теперь понимаю. Никто не должен пострадать, так что нет смысла учиться оказывать первую помощь. ;)   -  person cajwine    schedule 16.06.2012
comment
На самом деле, мне это интересно, и я тоже хотел бы это понять.   -  person Zagorax    schedule 16.06.2012
comment
@cajwine: Если кто-то пишет такой код (кроме шутки), то он идиот. Если вы окажетесь (например) в рабочей среде, где такой код допустим, вам следует уйти. Но в любом случае я бы порекомендовал изучить Perl в качестве первого шага!   -  person Oliver Charlesworth    schedule 16.06.2012
comment
Некоторое время мне казалось, что весь код Perl выглядит так...   -  person thkala    schedule 16.06.2012
comment
@OliCharlesworth, я действительно не понимаю, почему вы не можете принять это только как простую демонстрацию странных вещей, сделанных с помощью Perl. Я совершенно уверен, что никто не использует его в реальной жизни. Это не значит, что это, по крайней мере, интересно, что такой код может генерировать строку.   -  person Zagorax    schedule 16.06.2012
comment
@Zagorax: Потому что, во-первых, ОП заявил, что он / она не изучал Perl; мы не замена для этого. Во-вторых, как вопрос SO, он так же полезен, как вы можете объяснить, как работает пример XYZ из IOCCC? . Любой может написать ужасный, запутанный, запутанный фрагмент кода на любом языке, что не делает его интересным или полезным.   -  person Oliver Charlesworth    schedule 16.06.2012


Ответы (2)


В соответствии

.('_/).+{' ^ '/]@@_[

когда вы оцениваете ']' ^ '-', результатом будет буква p. ^ — это побитовая строковая операция, поэтому после этого мы следуем букве за буквой, чтобы получить результирующую строку.

Проверьте мой скрипт, он работает как ваш пример. Я надеюсь, что это поможет вам.

use v5.14;

# actually we obfuscated print and your word + "
# it looks like that (print).'"'.(yor_word")
my $print  = 'print';
my $string = 'special for stackoverflow by fxzuz"';

my $left  = get_obfuscated($print);
my $right = get_obfuscated($string);

# prepare result regexp
my $result = "'' =~ ('(?{'.($left).'\"'.($right).',\$/})');";

say 'result obfuscated ' .  $result;
eval $result;

sub get_obfuscated {

    my $string = shift;
    my @letters = split //, $string;

    # all symbols like :,&? etc (exclude ' and \)
    # we use them for obfuscation
    my @array = (32..38, 40..47, 58..64, 91, 93..95, 123..126);

    my $left_str = '';
    my $right_str = '';

    # obfuscated letter by letter
    for my $letter (@letters) {

        my @result;
        # get right xor letters
        for my $symbol (@array) {

            # prepare xor results
           my $result = ord $letter ^ $symbol;
           push @result, { left => $result, right => $symbol } if $result ~~ @array;
        }

        my $rand_elem = $result[rand $#result];
        $left_str  .= chr $rand_elem->{left};
        $right_str .= chr $rand_elem->{right};
    }

    my $obfuscated = "'$left_str' ^ '$right_str'";
    say "$string => $obfuscated";

    return $obfuscated;
}
person Pavel Vlasov    schedule 16.06.2012

Хитрость для понимания того, что здесь происходит, заключается в том, чтобы посмотреть на строку, построенную с помощью XOR и конкатенаций:

(?{print "Perl guys are smart",$/})

Это экспериментальная функция регулярных выражений вида (? {код}). Итак, то, что вы видите на терминале, является результатом

print "Perl guys are smart",$/

вызывается ''=~.... $/ — это разделитель входных записей Perl, который по умолчанию является новой строкой.

person flesk    schedule 16.06.2012