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();