International Obfuscated C Code Contest
Der International Obfuscated C Code Contest (kurz IOCCC) ist ein Programmierwettbewerb für die am kreativsten verschleierten C-Programme (engl.: to obfuscate: von lat. obfuscare, dt.: verdunkeln). Er wurde von 1984 bis 1996 jährlich veranstaltet und danach in unregelmäßigen Abständen.
Die Programmiersprache C ist eigentlich stark strukturiert und weitgehend typisiert, gibt dem Programmierer aber sehr große Freiheiten in Bezug auf die Art, wie der Quelltext aufgebaut sein soll. Zusätzlich erlaubt der sogenannte Präprozessor das Ersetzen von Textbausteinen mittels sogenannter Makros durch andere Textteile vor dem eigentlichen Übersetzungsschritt. Diese Freiheiten erlauben es, den semantisch gleichen Quellcode durch eine Vielzahl verschiedener tatsächlicher Quelltexte darzustellen, darunter auch solche, die völlig unverständlich oder verwirrend sind. So kann man ohne weiteres dem Schlüsselwort „true“ für „wahr“ den Wert „falsch“ zuweisen und umgekehrt. Wird Informatikprojekten keine saubere Struktur zugrunde gelegt oder sind die Programmierer unerfahren, können unverständliche und insbesondere unwartbare Programme auch unbeabsichtigt entstehen. Die Aufgabe im nicht ganz ernst gemeinten Wettbewerb besteht darin, absichtlich solchen Code zu schreiben.
Den Beiträgen werden jedes Jahr in zahlreichen Kategorien wie z. B. Worst Abuse of the C preprocessor (dt.: übelster Missbrauch des C-Präprozessors) oder Most Erratic Behavior (dt.: unberechenbarstes Verhalten) Preise verliehen.
Der IOCCC wurde von Landon Curt Noll und Larry Bassel initiiert, als diese über den furchtbaren Programmcode sprachen, den sie beruflich zu warten hatten. Sie entschieden sich, einen Wettbewerb für den schlimmstmöglichen C-Programmcode abzuhalten. Innerhalb der Begrenzung der Quellcodegröße auf wenige Kilobyte schaffen es die Wettbewerbsteilnehmer dennoch, komplizierte Dinge zu tun.
Einige Zitate der Gewinner von 2004:
- To keep things simple, I have avoided the C preprocessor and tricky statements such as "if", "for", "do", "while", "switch", and "goto". (dt.: Der Einfachheit halber habe ich den C-Präprozessor sowie verzwickte Anweisungen wie „if“, „for“, „do“, „while“, „switch“ und „goto“ vermieden.)
- We still aren't sure whether or not this is a useful program, but it’s the first atomic fission we've seen in the IOCCC. (dt.: Wir sind immer noch nicht sicher, ob dies ein nützliches Programm ist oder nicht, aber es ist die erste Kernspaltung, die wir im IOCCC gesehen haben.)
- Why not use the program to hide another program in the program? It must have seemed reasonable at the time. (dt.: Warum das Programm nicht benutzen, um in dem Programm ein anderes Programm zu verstecken? Zu der Zeit muss es sinnvoll erschienen sein.)
- The program implements an 11-bit ALU in the pre-processor. (dt.: Das Programm implementiert eine 11-Bit-ALU im Präprozessor.)
- I found that calculating prime numbers up to 1024 makes the program include itself over 6.8 million times. (dt.: Ich habe herausgefunden, dass sich bei der Berechnung von Primzahlen bis 1024 das Programm über 6,8 Mio. Mal in sich selbst einsetzt.)
Ein typischer Wettbewerbsbeitrag (von Brian Westley, 1988,<ref><templatestyles src="Webarchiv/styles.css" />{{#if:20131022115112
| {{#ifeq: 20131022115112 | *
| {{#if: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }} (Archivversionen)
| {{#iferror: {{#time: j. F Y|20131022115112}}
| {{#if: || }}Der Wert des Parameters {{#if: wayback | wayback | Datum }} muss ein gültiger Zeitstempel der Form YYYYMMDDHHMMSS sein!
| {{#if: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: 2022-11-18 16:47:07 InternetArchiveBot | 2022-11-18 16:47:07 InternetArchiveBot | }} | des Vorlage:Referrer }} vom {{#time: j. F Y|20131022115112}} im Internet Archive{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
}}
}}
| {{#if:
| {{#iferror: {{#time: j. F Y|{{{webciteID}}}}}
| {{#switch: {{#invoke:Str|len|{{{webciteID}}}}}
| 16= {{#if: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: 2022-11-18 16:47:07 InternetArchiveBot | 2022-11-18 16:47:07 InternetArchiveBot | }} | 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: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }} {{#ifeq: | [] | [ | ( }}{{#if: {{#if: 2022-11-18 16:47:07 InternetArchiveBot | 2022-11-18 16:47:07 InternetArchiveBot | }} | 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: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }} ({{#if: {{#if: 2022-11-18 16:47:07 InternetArchiveBot | 2022-11-18 16:47:07 InternetArchiveBot | }} | des Vorlage:Referrer}} vom {{#time: j. F Y|{{{webciteID}}}}} auf WebCite{{#if: | ; }}{{#ifeq: | [] | ] | ) }}
}}
| {{#if:
| Vorlage:Webarchiv/Today
| {{#if:
| Vorlage:Webarchiv/Generisch
| {{#if: www0.us.ioccc.org | {{#invoke:WLink|getEscapedTitle|www0.us.ioccc.org}} | {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988}} }}
}}}}}}}}{{#if:2022-11-18 16:47:07 InternetArchiveBot
| 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:20131022115112|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://www0.us.ioccc.org/years.html#1988}}
|| {{#if: || }}
}}{{#if: www0.us.ioccc.org
| {{#if: {{#invoke:WLink|isBracketedLink|www0.us.ioccc.org}}
| {{#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://www0.us.ioccc.org/years.html#1988%7Carchiv}} |-1
|| {{#ifeq: {{#invoke:Str|find|{{#invoke:Str|cropleft|http://www0.us.ioccc.org/years.html#1988%7C4}}%7Chttp}} |-1
|| {{#switch: {{#invoke:Webarchiv|getdomain|http://www0.us.ioccc.org/years.html#1988 }}
| 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}}
}}
}}
}}</ref> leicht angepasst zwecks Kompatibilität mit heutigen C-Compilern):
<syntaxhighlight lang="c">
#define _ F-->00||F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}
</syntaxhighlight>
Dieses Programm berechnet die Kreiszahl Pi, indem es seine eigene Fläche nutzt; einen präziseren Wert erhält man, indem man eine Programmversion mit mehr Kreisfläche verwendet.
Typisch für die Einsendungen sind u. a.:
- Das Layout des Quelltextes, der z. B. wie ein ASCII-Bild (siehe das Kreisbeispiel oben) formatiert wurde
- Präprozessor-Umdefinitionen, damit der Quellcode noch schwieriger zu entziffern ist
- selbstmodifizierender Programmcode
- Die Wettbewerbskategorie Worst abuse of the rules (dt.: übelster Missbrauch der Wettbewerbsregeln): In vielen Jahren wurde jeweils wenigstens ein Beitrag eingereicht, welcher so offensichtlich abwegig war, dass eine Neufassung der Regeln für den nächsten Wettbewerb erforderlich war. Dieser Preis ist verständlicherweise sehr begehrt. Als Beispiel sei das wohl kleinste Quine der Welt genannt: Der Beitrag war ein Programm der Länge Null, welches bei Ausführung null Bytes ausgab (also den eigenen Programmcode). Die Kompilierung des Programmes erforderte einige kreative Zweckentfremdungen des Makefiles.
Aus der Art des Wettbewerbs ergaben sich Programme, welche sich am Rande der C-Standards bewegten oder welche nur über selten verwendete Ausführungspfade der Compiler übersetzt werden konnten. Daher sind viele ältere Wettbewerbsbeiträge nicht mit einem modernen Compiler übersetzbar und einige verursachen sogar Compilerabstürze.
Andere Programmiersprachen
Der IOCCC soll lustig, erzieherisch und bildend sein, daher wurden gleichartige Wettbewerbe für Programmierer anderer Programmiersprachen ins Leben gerufen:
| Programmiersprache | Wettbewerb |
|---|---|
| Erlang | Obfuscated Erlang/OTP Competition |
| Perl | Obfuscated Perl Contest |
| Ruby | Obfuscated Ruby Contest |
Weblinks
- www.ioccc.org – Webpräsenz des IOCCC
- https://www.pcworld.com/article/478306/obfuscated_code_contest_returns.html
Einzelnachweise
<references />
- Seiten mit defekten Dateilinks
- Wikipedia:Vorlagenfehler/Vorlage:Webarchiv
- Wikipedia:Vorlagenfehler/Vorlage:Webarchiv/Archiv-URL
- Wikipedia:Vorlagenfehler/Parameter:URL
- Wikipedia:Vorlagenfehler/Parameter:Linktext
- Wikipedia:Vorlagenfehler/Vorlage:Webarchiv/Linktext fehlt
- Programmierwettbewerb
- Satire
- Erstverleihung 1984