Rok temu zabawiałem się publikując dość nietypowy skrypcik perlowy. Tego typu żarty wypada z czasem wyjaśnić, dlatego dzisiaj pokrótce opiszę jak go uzyskałem i jak można w łatwy sposób wygenerować coś podobnego.
Prawdziwa treść skryptu
Zagadkowy skrypt ma tak naprawdę tylko parę wierszy:
my @data = ( ["Najwyzszy czas", "Przeciez mozesz", "Musisz bardziej", "Powinienes", ], ["zaangazowac sie w", "wziac sie za", "postarac sie o", ], ["uczciwe", "porzadne", "systematyczne", "rozsadne", ], ["opisywanie zmian", "wpisywanie czasu do timesheeta", "testowanie", "obslugiwanie zgloszen", "uczestnictwo w spotkaniach", ], ); print "\n"; foreach my $tab (@data) { print $tab->[int(rand(scalar @$tab))], " "; } print "\n";
czyli jest mikroskopijną wersją generatora nowomowy. Pierwotnie chciałem umieścić tu więcej zachęcających tekstów ale aby wynikowy obrazek był niewielki, musiałem się ograniczać.
Konwerter
Za konwersję odpowiada moduł Acme::EyeDrops. Instalacja z CPAN to po prostu
$ cpan Acme::EyeDrops
Napisałem sobie następujący prosty skrypcik obfuscate.pl
:
use Acme::EyeDrops qw(sightly); my $source = shift @ARGV or die "Uruchamianie: $0 skrypt.pl\n"; my $shape = <<END; ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### ###################################### # # # # # ####### # # ###################################### # # # # ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### # # # # # ####### # # ###################################### # # # # ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### ############################### END print sightly( { #Shape => 'camel', ShapeString => $shape, SourceFile => $source, Regex => 1, Compact => 1, RemoveNewlines => 1, BorderGap => 2, BorderWidthLeft => 5, BorderWidthRight => 5, BorderWidthTop => 3, BorderWidthBottom => 3, } );
a następnie po prostu uruchomiłem go (w zrodlo.pl
był
oryginalny skrypt):
$ perl obfuscate.pl zrodlo.pl > wynik.pl
i w wynik.pl
powstał pożądany efekt:
''=~('(?{'.('`'|'%').('['^'-').('`'|'!').('`'|',').'"'.('`'|'-').('['^'"').(('{')^ '[').'\\@'.('`'|'$').('`'|'!').('['^'/').('`'|'!').('{'^'[').'='.('{'^'[').'([\\"' .('`'^'.').('`'|'!').('`'|'*').('['^',').('['^'"').('['^'!').('['^'(').('['^'!').( "\["^ '"'). ('{'^ '['). ('`'| '#').('['^'!').('`'|'!').('['^'(').''. '\\"' .','. ('{'^'[').'\\"'.('{'^'+').('['^"\)").( "\["^ '!'). ('`'|'%').('`'|'#').('`'|')').('`'|'%' ).''. ('['^ '!').('{'^'[').('`'|'-').('`'|('/')).( "\["^ '!'). ('`'|'%').('['^'(').('['^'!').'\\",'.( "\{"^ '['). '\\"'.('`'^'-').('['^'.').('['^"\(").( "\`"| ')'). ('['^'(').('['^'!').('{'^'[').('`'|'"' ).''. ('`'| '!').('['^')').('`'|'$').('['^('!')).( "\`"| ')'). ('`'|'%').('`'|'*').'\\",'.('{'^"\["). '\\"' .('{' ^'+').('`'|'/').('['^',').('`'|"\)").( "\`"| '.'). ('`'|')').('`'|'%').('`'|'.').('`'|'%' ).''. ('['^ '(').'\\",],[\\"'.('['^'!').('`'|'!'). ('`'| '!'). ('`'|'.').('`'|"'").('`'|'!').('['^'!' ).''. ('`'| '/').('['^',').('`'|'!').('`'|('#')).( "\{"^ '['). ('['^'(').('`'|')').('`'|'%').('{'^'[' ).''. ('['^ ',').'\\",'.('{'^'[').'\\"'.('['^','). ('['^ '!'). ('`'|')').('`'|'!').('`'|'#').('{'^'[' ).''. ('['^ ( '(')) .('`' | ( ')')) .('`' | ( '%')) .('{' ^'[').( "\["^ '!'). ( "\`"| '!'). ( '\\') .'",' .('{'^'[').'\\"'.('['^'+').('`'|'/').( "\["^ '('). ( ( '[')^ '/'). ( ( '`')| '!'). ('['^')').('`'|'!').('`'|'#').( '{'^'[').('['^'(').('`'|"\)").( "\`"| '%'). ('{'^'[').('`'|'/').'\\",],[\\' .'"'.('['^'.').('`'|'#').("\["^ '!'). ('`'| '#').('`'|')').('['^',').("\`"| '%').'\\",'.('{'^'[').('\\"').( "\["^ '+'). ('`'|'/').('['^')').('['^'!').( '`'|'!').('`'|'$').('`'|"\.").( "\`"| '%'). '\\",'.('{'^'[').'\\"'.('['^'(' ).('['^'"').('['^'(').('['^'/') .('`' |'%') .('`'|'-').('`'|'!').('['^'/'). ('['^'"').('`'|'#').('['^'!').( "\`"| '.'). ('`'|'%').'\\",'.('{'^'[').'\\' .'"'.('['^')').('`'|'/').("\["^ '!'). ('['^ '(').('`'|'!').('`'|'$').("\`"| '.').('`'|'%').('\\",],[\\"').( "\`"| '/'). ('['^'+').('`'|')').('['^'(').( '['^'"').('['^',').('`'|"\!").( "\`"| '.'). ('`'|')').('`'|'%').('{'^'[').( '['^'!').('`'|'-').('`'|"\)").( "\`"| '!'). ('`'|'.').'\\",'.('{'^'[').'\\' .'"'.('['^',').('['^'+').("\`"| ')'). ('['^ '(').('['^'"').('['^',').("\`"| '!').('`'|'.').('`'|')').("\`"| '%'). ('{'^ '[').('`'|'#').('['^'!').("\`"| '!').('['^'(').('['^'.').("\{"^ '['). ('`'| '$').('`'|'/').('{'^'[').("\["^ '/').('`'|')').('`'|'-').("\`"| '%'). ('['^ '(').('`'|'(').('`'|'%').("\`"| '%').('['^'/').('`'|'!').'\\",' .('{' ^'[') .'\\"'.('['^'/').('`'|'%').('[' ^'(').('['^'/').('`'|'/').('['^ ','). ('`'| ( '!')) .('`' | ( '.')) .('`' | ( ')')) .('`' |"\%"). '\\"' .','. ( "\{"^ '['). ( '\\') .'"'. ('`'|'/').('`'|'"').('['^'(').('`'|',' ).''. ('['^ ( ( '.')) ).''. ( ( '`')| "'"). ('`'|')').('['^',').('`'|'!').( '`'|'.').('`'|')').('`'|"\%").( "\{"^ '['). ('['^'!').('`'|"'").('`'|',').( '`'|'/').('['^'(').('['^"\!").( "\`"| '%'). ('`'|'.').'\\",'.('{'^'[').'\\' .'"'.('['^'.').('`'|'#').("\["^ '!'). ('`'| '%').('['^'(').('['^'/').("\`"| '.').('`'|')').('`'|'#').("\["^ '/'). ('['^ ',').('`'|'/').('{'^'[').("\["^ ',').('{'^'[').('['^'(').("\["^ '+'). ('`'| '/').('['^'/').('`'|'+').("\`"| '!').('`'|'.').('`'|')').("\`"| '!'). ('`'| '#').('`'|'(').'\\",],);'.('['^ '+').('['^')').('`'|')').("\`"| '.'). ('['^ '/').('{'^'[').'\\"\\\\'.("\`"| '.').'\\";'.('`'|'&').('`'|'/') .('[' ^')') .('`'|'%').('`'|'!').('`'|'#'). ('`'|'(').('{'^'[').('`'|'-').( "\["^ '"'). ('{'^'[').'\\$'.('['^'/').('`'| '!').('`'|'"').('{'^'[').'(\\@' .('`' |'$') .('`'|'!').('['^'/').('`'|'!'). ')'.('{'^'[').'\\{'.('{'^'[').( "\{"^ '['). ('{'^'[').('{'^'[').('['^'+').( '['^')').('`'|')').('`'|"\.").( "\["^ '/'). ('{'^'[').'\\$'.('['^'/').('`'| '!').('`'|'"').'->['.('`'|')'). ('`'| '.'). ('['^'/').'('.('['^')').(('`')| '!').('`'|'.').('`'|'$')."\(".( "\["^ '('). ('`'|'#').('`'|'!').('`'|',').( '`'|'!').('['^')').('{'^('[')). '\\@' .'\\' .'$'.('['^'/').('`'|'!').("\`"| '"').'))],'.('{'^'[').('\\"').( "\{"^ '['). '\\"' .';'. '\\}' .('['^'+').('['^')').('`'|')').('`'|'.').('['^'/').('{'^'[').'\\"\\\\'.('`'|"\."). '\\";"})');$:='.'^'~';$~='@'|'(';$^=')'^'[';$/='`'|'.';$,='('^'}';$\='`'|('!');$:= ')'^'}';$~='*'|'`';$^='+'^'_';$/='&'|'@';$,='['&'~';$\=','^'|';$:='.'^'~';$~="\@";
Zdefiniowałem tutaj własny kształt ale nie jest to konieczne, Acme::EyeDrops zawiera pokaźną paczkę zwierzątek, mapek, portretów itp. Co jest do dyspozycji można sprawdzić przeglądając katalog instalacji, na przykład:
$ nautilus \ `perl -M'Acme::EyeDrops qw(get_eye_dir)' \ -e 'print get_eye_dir(), "\n"'`
Używając któregoś z powyższych zadałbym zamiast ShapeString
opcję
Shape
, na przykład Shape => 'camel'
.
Jak to działa
Podstawową sztuczką jest użycie operatorów ^
i |
do konstruowania
normalnych liter ze znaków interpunkcyjnych. Przykładowo,
('`'|'%')
to po prostu
e
albo
('['^'"')
to
y
Pierwsze trzy wiersze powyższego obrazka to:
''=~(?{eval"my \@data = ([\"Najwyzsz
a całość to coś w stylu
''=~(?{eval" ...mój kod..."});
(przy czym w ramach mojego kodu niektóre znaki są escapeowane).
Za właściwe wykonanie kodu - wyliczonego przecież jako tekst - odpowiada polecenie eval
.
Malowanie obrazków jest możliwe, bo spacje i znaki nowego wiersza są nieznaczące dla wyrażeń wyliczających kod skryptu. I to właściwie tyle (może dodam jeszcze, że kilkadziesiąt końcowych znaków to nic nie robiący wypełniacz, dodany by namalowany został cały obrazek).
Dev::Bollocks
Skoro już o nowomowie, wspomnę o innym rozrywkowym module z CPAN. Dev::Bollocks to sympatyczny generator anglojęzycznych tekstów dla menedżera. Można go zainstalować poleceniem:
$ cpan Dev::Bollocks
po czym
$ perl -MDev::Bollocks \ -e 'print "We should ", Dev::Bollocks->rand(), "\n"'
będzie rzucało zwrotami w stylu
We should enthusiastically harness front-end synergies
albo
We should authoritatively customize front-end partnerships
Bardziej rozbudowany przykład to plik bollocks.pl
(po instalacji
można go znaleźć w katalogu o nazwie podobnej do
~/.cpan/build/Dev-Bollocks-0.06-K2IhhC/examples/bollocks.pl
), który
dodatkowo losuje różne długości i różne początki zdania.
A tak może wyglądać wersja CGI:
use strict; use CGI qw(:standard); use Dev::Bollocks; my $quote = Dev::Bollocks->rand(); # (5) print header(), start_html("Your Manager is talking to you"), p("We should $quote"), end_html();