Как работает этот запутанный код Perl? - PullRequest
7 голосов
/ 23 февраля 2010

Как этот код работает вообще?

#!/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;}

Ответы [ 3 ]

16 голосов
/ 23 февраля 2010

Давайте сначала введем это через 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 секунды. Возврат каретки заставляет их перезаписывать друг друга, чтобы была видна анимация. Последние несколько строк никогда не достигаются и, таким образом, являются поддельными.

14 голосов
/ 23 февраля 2010

Данные из файла загружаются в программу, называемую интерпретатором Perl. Интерпретатор анализирует код и преобразует его в серию «кодов операций» - языка байт-кода, который находится на полпути между кодом Perl и машинным языком, на котором работает код. Если в процессе преобразования не было ошибок (называемых «компиляцией»), то код выполняется другой частью интерпретатора Perl. Во время выполнения программа может изменять различные состояния машины, такие как выделение, освобождение, чтение и запись в память или использование ввода / вывода и других функций системы.

(CW - Больше хардкорных хакеров, чем я, можете исправить любые ошибки или неправильные представления и добавить больше информации)

8 голосов
/ 23 февраля 2010

Здесь не происходит никакой магии, только запутывание. Давайте посмотрим на высоком уровне. Первое, на что нужно обратить внимание, это то, что позже каждый символ в строке интерпретируется так, как если бы он был предыдущим:

[1] map{chr(ord()-1)} ...

Таким образом, строка типа «6qD» приведет к «5rC» (символы перед «6», «q» и «D» соответственно). Основная достопримечательность - массив строк в начале:

[2] ">>>E!)",">>>E)",">>>E",">>>",">>",">",""

Это определяет последовательность "масок", которые мы подставим позже, в эту строку:

[3] "9$_*\x{0e}"

Они будут вставлены в $_ точку. Строка \x{0e} представляет шестнадцатеричный управляющий символ; обратите внимание, что \x{0d}, символ непосредственно перед ним, является возвратом каретки. Вот что подставится в [3], когда мы сделаем [1].

Перед тем, как строка [3] собрана, мы добавляем число !, равное i, к каждому элементу в [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 добавляет те же элементы в обратном порядке, создавая цикл.

В этот момент вы должны увидеть появление шаблона, который производит анимацию. Теперь это просто вопрос прохождения каждого шага анимации и обратно, что выполняется остальной частью сценария. Временная задержка каждого шага определяется оператором select:

[5] select undef, undef, undef, 0.25

, который говорит нам ждать 250 миллисекунд между каждой итерацией. Вы можете изменить это, если хотите, чтобы оно ускорялось или замедлялось.

...