Just another Perl hacker
Just another Perl hacker (abgekürzt JAPH) steht für ein in der Programmiersprache Perl geschriebenes kurzes Computerprogramm, das lediglich den Text „Just another Perl hacker“ ausgibt, seine Funktionsweise im Quelltext dabei aber möglichst wirkungsvoll verschleiert. Ein solches Programm dient experimentellen Zwecken sowie der Unterhaltung der Programmierer und hat darüber hinaus keinerlei praktischen Nutzen, obgleich die Analyse der Funktionsweise eines JAPHs für Perl-Programmierer außerordentlich lehrreich sein kann.
Methodik der Verschleierung
Zum Zweck der Verschleierung ({{#invoke:Vorlage:lang|full|CODE=en|SCRIPTING=Latn|SERVICE=englisch}}) wird der Programmcode zumeist – unter Ausnutzung auch der abwegigsten syntaktischen Möglichkeiten der Programmiersprache Perl – derart kryptisch formuliert, dass man ihm seine Funktion (die Ausgabe von „Just another Perl hacker“) selbst auf den zweiten Blick kaum ansieht. Nicht selten wird dem Quelltext darüber hinaus durch kreatives Layout ein originelles und für Programmcode völlig untypisches Erscheinungsbild verliehen. Beides dient der Verschleierung der eigentlichen Funktion und/oder der Funktionsweise des Programms, oder gar der Tatsache, dass es sich bei dem vorliegenden Text überhaupt um ein Computerprogramm handelt.
Historie
Die „Programmierdisziplin“ JAPH wurde vermutlich Anfang der 1990er Jahre durch Randal L. Schwartz begründet, der bei Postings in die Newsgroup „comp.lang.perl“ (Vorgänger der heutigen Newsgroup „comp.lang.perl.misc“) immer ein JAPH in seine Signature integrierte. Auch heute noch werden JAPHs entweder im Rahmen von Programmierwettbewerben (z. B. dem Obfuscated Perl Contest) entwickelt, oder just for fun – als kreative Fingerübung der Perl-Programmierer.
Beispiele
Ein Perl-Programm für die Ausgabe von „Just another Perl hacker“ sähe normalerweise so aus:
<syntaxhighlight lang="perl">print "Just another Perl hacker";</syntaxhighlight>
Verschleierung (Obfuscation) kann beispielsweise erreicht werden durch Einbinden dieser – an sich verständlichen – Anweisung in undurchsichtigen und funktionslosen Code:
<syntaxhighlight lang="perl">$_='987;s/^(\d+)/$1-1/e;$1?eval:print"Just another Perl hacker"';eval;</syntaxhighlight>
Ein JAPH kann auch wie purer Datenmüll aussehen, obwohl er tatsächlich sowohl die auszugebenden Zeichen als auch den Code für deren Ausgabe enthält. In diesem Fall wurde der auszugebende Code durcheinandergewürfelt und der Perl-Einzeiler sortiert den Text zur Ausgabe wieder zurück:
<syntaxhighlight lang="perl">$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;</syntaxhighlight>
Manche JAPHs sind weniger schwer verständlich, scheinen aber einem gänzlich anderen Zweck zu dienen als der Ausgabe von „Just another Perl hacker“. Beim folgenden Beispiel von Randal L. Schwartz wurde der auszugebende Text mit einem festen Textstring umcodiert. Der Einzeiler macht lediglich die Umcodierung rückgängig:
<syntaxhighlight lang="perl">$_ = "wftedskaebjgdpjgidbsmnjgc";
tr/a-z/oh, turtleneck Phrase Jar!/; print;</syntaxhighlight>
Das folgende, nur unter Unix lauffähige JAPH-Programm von Eric Roode besteht ausschließlich aus Sonderzeichen; alphanumerische Zeichen und Leerraum fehlen gänzlich.
<syntaxhighlight lang="perl">`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=( $!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++; $_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
- $,++;$^|=$";`$_$\$,$/$
- $;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`</syntaxhighlight>
Nachstehendes Programm von Mark Jason Dominus gewann den 2. Preis im fünften Obfuscated Perl Contest. Es erzeugt aus dem in den Quellcode eingebetteten rückwärts geschriebenen Text (rechts in der ersten Zeile) in absichtlich komplizierter Weise die Ausgabe „Just another Perl / Unix hacker“.<ref>Ausführliche Erklärung zum vorletzten Beispiel (englisch)</ref>
<syntaxhighlight lang="perl">@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{ @p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord ($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&& close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print</syntaxhighlight>
Das folgende Programm ist ein „bilingualer“ JAPH: Der Code kann sowohl vom Perl-Interpreter als auch vom Interpreter der esoterischen Programmiersprache Brainfuck ausgeführt werden. Die Ausgabe ist in beiden Fällen „Just another Perl Hacker“. Der große Block mit den Plus- und Minuszeichen ist im Wesentlichen der Brainfuck-Code (mit reduziertem Instruktionssatz), die erste Zeile ist Perl-Code und implementiert einen Brainfuck-Interpreter für ebendiesen reduzierten Satz an Instruktionen.<ref>Kurze Erläuterung zum letzten Beispiel (englisch)</ref>
<syntaxhighlight lang="perl">/[+-]/&&eval"\$/$_$_"||/\x2e/&&print chr$/for qw!
=====================================
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . - - . + . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + . + . + + + + + . - - - - - - - - - - - - . - - - . + + + + + + + + + + + + + . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + . - - - - - - . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + + + + + + + . + + . + + + + + + + + . - - - - - - . + + + + + + + + + + + + + . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - -
=====================================
A bilingual JAPH. Valid code in Perl & brainf***!</syntaxhighlight>
Siehe auch
- Obfuscated Perl Contest
- Obfuscator – Hilfsmittel zur Verschleierung von Programmen
Weblinks
- Teodor Zlatanov: <templatestyles src="Webarchiv/styles.css" />{{#if:20070208125018
| {{#ifeq: 20070208125018 | *
| {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }} (Archivversionen)
| {{#iferror: {{#time: j. F Y|20070208125018}}
| {{#if: || }}Der Wert des Parameters {{#if: wayback | wayback | Datum }} muss ein gültiger Zeitstempel der Form YYYYMMDDHHMMSS sein!
| {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: | {{{archiv-bot}}} | }} | des Vorlage:Referrer }} vom {{#time: j. F Y|20070208125018}} im Internet Archive{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
}}
}}
| {{#if:
| {{#iferror: {{#time: j. F Y|{{{webciteID}}}}}
| {{#switch: {{#invoke:Str|len|{{{webciteID}}}}}
| 16= {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: | {{{archiv-bot}}} | }} | des Vorlage:Referrer }} vom {{#time: j. F Y| 19700101000000 + {{#expr: floor {{#expr: {{#invoke:Str|sub|{{{webciteID}}}|1|10}}/86400}} }} days}} auf WebCite{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
| 9 = {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: | {{{archiv-bot}}} | }} | des Vorlage:Referrer}} vom {{#time: j. F Y| 19700101000000 + {{#expr: floor {{#expr: {{#invoke:Str|sub|{{#invoke:Expr|base62|{{{webciteID}}}}}|1|10}}/86400}} }} days}} auf WebCite{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
| #default= Der Wert des Parameters {{#if: webciteID | webciteID | ID }} muss entweder ein Zeitstempel der Form YYYYMMDDHHMMSS oder ein Schüsselwert mit 9 Zeichen oder eine 16-stellige Zahl sein!{{#if: || }}
}}
| c|{{{webciteID}}}}} {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }} ({{#if: {{#if: | {{{archiv-bot}}} | }} | des Vorlage:Referrer}} vom {{#time: j. F Y|{{{webciteID}}}}} auf WebCite{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
}}
| {{#if:
| Vorlage:Webarchiv/Today
| {{#if:
| Vorlage:Webarchiv/Generisch
| {{#if: Cultured Perl: The Elegance of JAPH | {{#invoke:WLink|getEscapedTitle|Cultured Perl: The Elegance of JAPH}} | {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}} }}
}}}}}}}}{{#if:
| Vorlage:Webarchiv/archiv-bot
}}{{#invoke:TemplatePar|check
|all = url=
|opt = text= wayback= webciteID= archive-is= archive-today= archiv-url= archiv-datum= ()= archiv-bot= format= original=
|cat = Wikipedia:Vorlagenfehler/Vorlage:Webarchiv
|errNS = 0
|template = Vorlage:Webarchiv
|format = *
|preview = 1
}}{{#ifexpr: {{#if:20070208125018|1|0}}{{#if:|+1}}{{#if:|+1}}{{#if:|+1}}{{#if:|+1}} <> 1
| {{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Genau einer der Parameter 'wayback', 'webciteID', 'archive-today', 'archive-is' oder 'archiv-url' muss angegeben werden.|1}}
}}{{#if:
| {{#switch: {{#invoke:Webarchiv|getdomain|{{{archiv-url}}}}}
| web.archive.org =
{{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Im Parameter 'archiv-url' wurde URL von Internet Archive erkannt, bitte Parameter 'wayback' benutzen.|1}}
| webcitation.org =
{{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Im Parameter 'archiv-url' wurde URL von WebCite erkannt, bitte Parameter 'webciteID' benutzen.|1}}
| archive.today |archive.is |archive.ph |archive.fo |archive.li |archive.md |archive.vn =
{{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Im Parameter 'archiv-url' wurde URL von archive.today erkannt, bitte Parameter 'archive-today' benutzen.|1}}
}}{{#if:
| {{#iferror: {{#iferror:{{#invoke:Vorlage:FormatDate|Execute}}|}}
| {{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Der Wert des Parameter 'archiv-datum' ist ungültig oder hat ein ungültiges Format.|1}}
| }}
| {{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Der Pflichtparameter 'archiv-datum' wurde nicht angegeben.|1}}
}}
| {{#if:
| {{#if: || }}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Der Parameter 'archiv-datum' ist nur in Verbindung mit 'archiv-url' angebbar.|1}}
}}
}}{{#if:{{#invoke:URLutil|isHostPathResource|http://www-128.ibm.com/developerworks/linux/library/l-japh.html}}
|| {{#if: || }}
}}{{#if: Cultured Perl: The Elegance of JAPH
| {{#if: {{#invoke:WLink|isBracketedLink|Cultured Perl: The Elegance of JAPH}}
| {{#if: || }}
}}
| {{#if: || }}
}}{{#switch:
|addlarchives|addlpages= {{#if: || }}{{#if: 1 |}}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: enWP-Wert im Parameter 'format'.|1}}
}}{{#ifeq: {{#invoke:Str|find|http://www-128.ibm.com/developerworks/linux/library/l-japh.html%7Carchiv}} |-1
|| {{#ifeq: {{#invoke:Str|find|{{#invoke:Str|cropleft|http://www-128.ibm.com/developerworks/linux/library/l-japh.html%7C4}}%7Chttp}} |-1
|| {{#switch: {{#invoke:Webarchiv|getdomain|http://www-128.ibm.com/developerworks/linux/library/l-japh.html }}
| abendblatt.de | daserste.ndr.de | inarchive.com | webcitation.org =
| #default = {{#if: || }}{{#if: 1 |}}{{#invoke:TemplUtl|failure| Fehler bei Vorlage:Webarchiv: Archiv-URL im Parameter 'url' anstatt URL der Originalquelle. Entferne den vor der Original-URL stehenden Mementobestandteil und setze den Archivierungszeitstempel in den Parameter 'wayback', 'webciteID', 'archive.today' oder 'archive-is' ein, sofern nicht bereits befüllt.|1}}
}}
}}
}}. In: ibm.com, 1. Juli 2001 (englisch).
- Eine Sammlung von 224 JAPHs (englisch).
Einzelnachweise
<references />