PDF, 97KB - Westfälische Wilhelms-Universität Münster
PDF, 97KB - Westfälische Wilhelms-Universität Münster
PDF, 97KB - Westfälische Wilhelms-Universität Münster
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
<strong>Westfälische</strong> <strong>Wilhelms</strong>-<strong>Universität</strong> <strong>Münster</strong><br />
Ausarbeitung<br />
Schützbarkeit von Algorithmen<br />
(im Rahmen des Seminars „Informatik und Recht“)<br />
Christian Sonnenberg<br />
Themensteller: Prof. Dr. Herbert Kuchen<br />
Betreuer: Prof. Dr. Herber Kuchen<br />
Institut für Wirtschaftsinformatik<br />
Praktische Informatik in der Wirtschaft
Inhaltsverzeichnis<br />
1 Einleitung...................................................................................................................1<br />
2 Das Konzept „Algorithmus“ ......................................................................................1<br />
2.1 Determinanten des Algorithmenbegriffs...........................................................1<br />
2.2 Vom Problem zum Algorithmus .......................................................................7<br />
2.3 Reverse Engineering - vom Maschinencode zum Quellcode .........................13<br />
3 Aspekte der Schützbarkeit von Algorithmen ...........................................................15<br />
3.1 Urheberrecht und Patentrecht..........................................................................15<br />
3.1.1 Algorithmen und das Patentrecht ................................................................15<br />
3.1.2 Äquivalenz von Programmen und Schriftwerken .......................................16<br />
3.2 Einfluss der Erfindungshöhe auf die Schutzbedürftigkeit ..............................18<br />
3.3 Abhängigkeit der Schutzbedürftigkeit von der Verfeinerungsstufe...............20<br />
3.4 Open – Source .................................................................................................21<br />
4 Fazit..........................................................................................................................22<br />
A Bytecode des Beispiels „Insertion Sort“ ..................................................................23<br />
B Ergebnis der Anwendung eines Java Obfuscators – „Insertion Sort“......................25<br />
C Quicksort – Algorithmus..........................................................................................27<br />
Literaturverzeichnis.........................................................................................................28<br />
II
Kapitel 1: Einleitung<br />
1 Einleitung<br />
In den letzten Jahren wurde dem Gebiet des Softwarerechts eine gestiegene<br />
Aufmerksamkeit zuteil. Vielfach wird bemängelt, die Rechtssprechung würde mit einer<br />
anachronistischen Terminologie vergeblich versuchen, Regelungen für eine noch junge,<br />
dynamische und innovative Informationsgesellschaft treffen zu können.<br />
Einige Vertreter der Softwarebranche merken beispielsweise schon seit längerem<br />
kritisch an, dass ein Schutz für Programme nicht ausreichend sei, vielmehr wäre es von<br />
Interesse, speziell auch Algorithmen schützen lassen zu können.<br />
Das Thema der Schützbarkeit von Algorithmen wird in dieser Arbeit aufgegriffen.<br />
Vor dem juristischen Hintergrund erscheint es zunächst wichtig, zu klären, was unter<br />
einem Algorithmus zu verstehen ist. Überdies erscheint es notwendig, zu erläutern,<br />
wovon die Schutzwürdigkeit eines Algorithmus abhängig ist und welche Implikationen<br />
ein derartiger Schutz mit sich bringt.<br />
Diese Fragestellungen sollen mit dieser Arbeit der Reihe nach aufgegriffen werden.<br />
2 Das Konzept „Algorithmus“<br />
In diesem Kapitel versuche ich, die wesentlichen Eigenschaften eines Algorithmus<br />
herauszustellen und die für das Thema relevanten „algorithmischen“ Aspekte genauer<br />
zu untersuchen, ohne dabei jedoch den Versuch zu unternehmen, eine konkrete<br />
Definition zu entwickeln.<br />
Ziel dieses Kapitels soll es sein, eine genaue Vorstellung darüber zu erlangen, was unter<br />
dem algorithmischen Konzept im Kontext der Informatik zu verstehen ist und welche<br />
Implikationen dies in der praktischen Anwendung mit sich bringt.<br />
2.1 Determinanten des Algorithmenbegriffs<br />
Auch wenn der Begriff des Algorithmus als zentral und fundamental für die Informatik<br />
angesehen wird, so kann er nicht losgelöst vom Begriff des Problems betrachtet werden,<br />
welcher ebenso zentral in der Informatik ist. Ohne die Existenz konkreter Probleme (im<br />
informatorischen Sinne) wäre eine Diskussion über Algorithmen hinfällig.<br />
1
Kapitel 2: Das Konzept „Algorithmus“<br />
Ein Algorithmus gilt als ein Verfahren zur Lösung eines Problems. Ein Problem ist<br />
hierbei eine Fragestellung, die hinreichend genau beschrieben ist. Eine Problemklasse<br />
ist eine Menge von ähnlichen Fragestellungen (mit jeweils unterschiedlichen konkreten<br />
Eingabewerten), die auch Instanzen genannt werden [Wi97, S. 10]. Somit ist zusätzlich<br />
festzuhalten, dass Algorithmen konkrete Probleme einer bestimmten Problemklasse<br />
lösen. Eine Problemklasse stellt z.B. das Suchen eines Elementes in einer Menge dar,<br />
das Sortieren von Elementen, das Lösen linearer Gleichungen oder auch die<br />
Berechnung des kürzesten Weges in einem Navigationssystem. Instanzen der Klasse<br />
Suche eine Element einer Menge wären z.B.: „ist 9 ∈ {7, 9, 14, 21}?“ oder<br />
„ist 1 ∈ {2, 3, 4}?“<br />
Typischerweise wird ein Algorithmus für eine bestimmte Problemklasse entworfen und<br />
löst daher nur Probleme derselben Problemklasse. Allerdings existieren sehr oft für eine<br />
Problemklasse mehrere Algorithmen.<br />
Ein Algorithmus ist folglich spezifisch. In diesem Sinne erfüllt jeder Algorithmus eine<br />
bestimmte funktionale Spezifikation. Diese Eigenschaft resultiert aus einer formaleren<br />
Sichtweise auf Probleme und betont den Verarbeitungsaspekt [Wi97, S. 10]. Die<br />
Problemklasse wird hierbei als Funktion zwischen Eingaben (Input) und Ausgaben<br />
(Output) beschrieben. Aufgabe eines Verfahrens zum Lösen eines Problems ist dann die<br />
Berechnung (Verarbeitung) der Ausgabe auf der Grundlage der Eingabe.<br />
Algorithmen benötigen daher eine Menge von Input – Werten, welche auch leer sein<br />
kann, und transformieren diese in einen Output gemäß einer funktionalen Spezifikation.<br />
Problemklasse K<br />
Problemklasse K’<br />
Problem P1<br />
Problem P2<br />
Problem P1<br />
Problem P2<br />
INPUT<br />
INPUT<br />
K-Algorithmus<br />
OUTPUT<br />
K’-Algorithmus<br />
OUTPUT<br />
Lösung P1<br />
Lösung P1<br />
Lösung P1<br />
Lösung P1<br />
Abbildung 1: Algorithmen vs. Probleme u. Problemklassen<br />
2
Kapitel 2: Das Konzept „Algorithmus“<br />
Algorithmen sind häufig parametrisierbar [He92, S. 20] Das ist vor allem dann wichtig,<br />
wenn der Algorithmus mehrere Probleme einer Problemklasse lösen können muss, was<br />
in den meisten Fällen erwünscht ist. Die Auswahl des Einzelfalls erfolgt hierbei über<br />
Parameter. Diese Eigenschaft wird als Allgemeinheit von Algorithmen bezeichnet.<br />
Unter Berücksichtigung des informatorischen Kontextes wird von einem Algorithmus<br />
gefordert, dass er maschinell ausführbar ist. Kennzeichnend für einen Algorithmus ist<br />
dabei, dass die Verarbeitung des Inputs zum Output durch eine endliche Abfolge von<br />
elementaren Einzelschritten erfolgt.<br />
Im Hinblick auf die Möglichkeit der maschinellen Realisierung eines Verfahrens zur<br />
Lösung eines Problems ist es erforderlich, dass die Lösungsvorschrift nicht in einer<br />
beliebigen, sondern in einer endlichen, präzisen Beschreibung unter Verwendung<br />
effektiver, elementarer Verarbeitungsschritte erfolgt [Wi97, S. 10].<br />
Die Forderung nach einer endlichen Beschreibung ist notwendig, da es sich bei einem<br />
Algorithmus um eine Form von Information handelt, die wie alles andere eine<br />
(maschinelle) Repräsentation, also eine äußere Form besitzen muss. Wenn diese Form<br />
handhabbar sein soll, muss diese Repräsentation natürlich endlich sein, sonst könnte<br />
man sie im Falle einer sprachlichen Formulierung nicht vollständig aufschreiben [Wi97,<br />
S. 10]. Zum Aspekt der Repräsentation bzw. Darstellung von Algorithmen wird an<br />
späterer Stelle noch genauer eingegangen.<br />
Eine präzise Beschreibung soll Missverständnisse bei der Interpretation ausschließen.<br />
Die Bedeutung und die Auswirkung eines jeden Einzelschrittes muss für jeden<br />
auftretenden Fall genau festgelegt sein. Dies wird oft auch als Definitheit bezeichnet.<br />
Um dies zu gewährleisten, bedarf es einer vorgegebenen Sprache mit eindeutig<br />
festgelegter Interpretation, die hinreichend exakt ist [Wi97, S. 10]. Zu diesem Zweck<br />
wurden Maschinensprachen und Programmiersprachen eingeführt. Die in diesen<br />
Sprachen zulässigen Beschreibungsmittel besitzen alle eine klare Bedeutung und<br />
ermöglichen so eine adäquate Spezifizierung von maschinell ausführbaren Algorithmen.<br />
Algorithmenspezifikationen werden, wie später noch erläutert wird, typischerweise auf<br />
unterschiedlichen Abstraktionsniveaus formuliert. Auf einer oberen Abstraktionsebene<br />
geschieht dies oft auf eine semiformalen Art und Weise durch den Gebrauch von<br />
Umgangssprache in Kombination mit einer repräsentativen Kontrollstruktursyntax von<br />
3
Kapitel 2: Das Konzept „Algorithmus“<br />
Programmiersprachen (Pseudocode). Auch auf diesen höheren Abstraktionslevels gilt<br />
die Forderung nach einer (hinreichend) präzisen Beschreibung.<br />
Nicht die konkrete Realisierung auf einer realen Maschine ist entscheidend bei der<br />
Formulierung eines Algorithmus, sondern die Idee der Komposition der elementaren<br />
Operationen, um ausgehend vom Input einen spezifikationskonformen Output zu<br />
erhalten. Dies bedeutet insbesondere, dass diese Idee so genau (präzise) formuliert wird,<br />
als dass das algorithmisch formulierte Konzept von beliebigen Personen, denen diese<br />
Formulierung vorliegt, mental und zusätzlich auch formal jeweils identisch reproduziert<br />
wird. Diese Forderung stellt somit sicher, dass Algorithmen zwischen Personen<br />
kommuniziert werden können, ohne dass die Idee und die Details der Lösungsfindung<br />
aufgrund von Ambiguität verloren gingen.<br />
„… the reader should not expect to read an algorithm as he reads a novel; such an<br />
attempt would make it pretty difficult to understand what is going on; An algorithm<br />
must be seen to be believed…” [Kn73, S. 4]<br />
Charakteristisch für Algorithmen ist, dass deren Ausführung beim Ausführenden<br />
(„Prozessor“) keine Intelligenz, Einsicht, Verstand, Intuition oder schöpferische<br />
Phantasie voraussetzt [Wa89, S. 15]. Daher hat eine algorithmische Beschreibung<br />
insbesondere hinreichend präzise zu erfolgen. Somit sind Algorithmen wie geschaffen<br />
dafür, ein spezifiziertes Lösungsverfahren maschinell (computergestützt im engeren<br />
Sinne) umzusetzen und zur Ausführung zu bringen, denn speziell Maschinen sind als<br />
solche weder intelligent noch in der Lage, intuitiv handeln zu können. Eine Maschine<br />
muss folglich „Schritt für Schritt“ angeleitet werden, um das gewünschte Verhalten<br />
(gemäß der algorithmischen Spezifikation) zu realisieren ohne dass dafür ein<br />
inhaltliches Verständnis für das Vorgehen seitens der Maschine erforderlich ist. Die<br />
Forderung nach der Ausführbarkeit eines Algorithmus auf einer konkreten Maschine<br />
(Computer) hingegen ist nicht charakteristisch für das Konzept von Algorithmen,<br />
wenngleich die prinzipielle Möglichkeit der maschinellen Ausführung aufgrund der<br />
Natur des Konzeptes implizit gegeben ist.<br />
Somit steht die Idee, um die herum ein Algorithmus konstruiert wird, im Mittelpunkt<br />
der Betrachtung. Daher ist es sehr wichtig, die Idee unmissverständlich und präzise<br />
kommunizieren zu können und zwar auf allen Abstraktionsebenen einer<br />
algorithmischen Formulierung. Allerdings ist der Begriff der Präzision auf höheren<br />
Abstraktionsstufen nicht im Sinne von „Beschreibung in allen Einzelheiten“ zu<br />
4
Kapitel 2: Das Konzept „Algorithmus“<br />
verstehen. Vielmehr handelt es sich auf einer sehr hohen Abstraktionsstufe um<br />
konzeptionelle und gedankliche Skizzen eines Algorithmus, welche aber schon die<br />
wesentliche Idee und das Konzept der Lösungsstrategie dokumentieren und damit<br />
insofern präzise sind, als dass aus dieser algorithmischen Skizze unmittelbar jeweils<br />
detailliertere Beschreibungen abgeleitet werden können (-> hinreichende Präzision).<br />
Der Aspekt der Effektivität der Arbeitsschritte ist ebenso von Bedeutung. Effektivität in<br />
diesem Sinne ist dann gegeben, wenn alle Operationen oder Einzelschritte eines<br />
Algorithmus hinreichend einfach und elementar sind, so dass sie prinzipiell auch von<br />
einem Menschen mit Bleistift und Papier exakt und in einer endlichen Zeit ausgeführt<br />
werden könnten [Kn73 S. 6].<br />
Bei der Beschreibung eines Algorithmus ist zwischen den elementaren Operationen<br />
einerseits und den Vorschriften, wie und in welcher Reihenfolge sie angewandt werden<br />
sollen, zu unterscheiden [Wi97 S. 11]. Ein Elementarschritt ist von einer Maschine in<br />
einem Schritt (als unteilbare Aktion) auszuführen. Bezüglich der Beschreibung der<br />
Abfolge der Elementarschritte sind folgende Strukturelemente eines Algorithmus<br />
anwendbar: Sequenz; Auswahl von Fällen mit anschließender Entscheidung, was als<br />
nächstes ausgeführt wird; feste Wiederholungen von Schrittfolgen sowie bedingte<br />
Wiederholungen.<br />
Nachdem nun die prinzipielle Art der Beschreibung von Algorithmen diskutiert wurde,<br />
sollen jetzt noch einige Eigenschaften von Algorithmen besprochen werden.<br />
Ein Algorithmus heißt terminierend genau dann, wenn der Algorithmus für alle<br />
erlaubten Eingaben nach endlich vielen Schritten beendet wird. Für die praktische<br />
Anwendung sind in den meisten Fällen primär terminierende Algorithmen interessant.<br />
Einige (nicht unbedeutende) Ausnahmen bilden hier Betriebssystemfunktionen oder<br />
Prozess-Steuerungsalgorithmen [He92, S. 21]. Tatsächlich ist eine Forderung nach der<br />
Terminierung nicht präzise genug für die praktische Verwendung [Kn73, S. 6]. Ein<br />
Algorithmus, welcher beispielsweise ermitteln soll, ob bei einer Partie Schach der<br />
Spieler „weiß“ zwingend gewinnt, ist zwar endlich und terminiert, aber wir werden das<br />
Ergebnis in unserem Leben vielleicht niemals erfahren, da ein solcher Algorithmus sehr<br />
viel Berechnungszeit beanspruchen wird. Ein brauchbarer Algorithmus sollte daher<br />
nicht irgendwie oder irgendwann, sondern möglichst in einer akzeptablen Anzahl von<br />
Schritten terminieren.<br />
5
Kapitel 2: Das Konzept „Algorithmus“<br />
Determinismus ist eine weitere typische Eigenschaft von Algorithmen. Diese ist immer<br />
dann gegeben, wenn die Reihenfolge der Verarbeitungsschritte des betrachteten<br />
Algorithmus stets eindeutig festgelegt ist, in der Auswahl der Verarbeitungsschritte also<br />
keine Wahlmöglichkeit besteht. Dies heißt dann auch, dass verschiedene Abarbeitungen<br />
eines Algorithmus für die gleiche Eingabe immer die gleiche Folge von Schritten<br />
ausführen [Wi97, S.12]. Determinismus ist nicht immer unbedingt notwendig oder<br />
erwünscht. Einige Problemklassen beispielsweise im Bereich der künstlichen Intelligenz<br />
verbieten gar die Anwendung deterministischer Algorithmen, da hier insbesondere mit<br />
stochastischen Modellen gearbeitet wird und somit auch die Reihefolge der<br />
Verarbeitungsschritte zwingend stochastisch getrieben ist. Jede neue Abarbeitung eines<br />
solchen nicht deterministischen Algorithmus bei unverändertem Input würde jeweils<br />
eine andere Reihenfolge bei der Ausführung von Einzelschritten bewirken und<br />
gegebenenfalls auch ein anderes Ergebnis.<br />
Eine ganz wesentliche Eigenschaft ist zudem die Determiniertheit von Algorithmen. Ist<br />
das Ergebnis der Abarbeitung für alle Eingaben eindeutig festgelegt, so ist ein<br />
Algorithmus determiniert. Sinnvolle Beispiele für nicht determinierte Algorithmen sind<br />
nur schwer zu finden, da Nicht-Determiniertheit der Auffassung, dass ein Algorithmus<br />
eine funktionale Spezifiktion erfüllen soll (zumindest auf den ersten Blick),<br />
widerspricht [Wi97, S. 13]. Nach obigen Erläuterungen ist aber auch klar, dass<br />
Algorithmen denkbar sind, bei denen der Output nicht unbedingt von vornherein für alle<br />
Eingaben eindeutig festgelegt ist, für ein und dieselbe Eingabe (-menge) also jeweils<br />
unterschiedliche aber gültige Ergebnisse erzielt werden können. Vornehmlich trifft dies<br />
auf Algorithmen zu, die entweder auf stochastischen Modellen arbeiten (siehe<br />
künstliche Intelligenz) oder Algorithmen, deren Abarbeitung mit realen Zufällen<br />
verknüpft ist (z.B. Algorithmen basierend auf Warteschlangen, Transaktionen;<br />
Betriebssystemalgorithmen).<br />
Ein Algorithmus heißt sequentiell, wenn zu jedem Zeitpunkt nur ein elementarer<br />
Arbeitsschritt ausgeführt werden kann. Parallel ist er hingegen, wenn gewisse<br />
Arbeitsschritte nebeneinander (zur gleichen Zeit) ausgeführt werden. Es sei angemerkt,<br />
dass die Eigenschaft sowohl einem Algorithmus zukommen kann, als auch der<br />
Ausführung eines Algorithmus [Wi97, S. 13].<br />
Wie aus den obigen Erläuterungen deutlich wird, muss ein Algorithmus nicht alle<br />
Eigenschaften auf einmal erfüllen. Ein idealtypischer Algorithmus sollte zwar<br />
6
Kapitel 2: Das Konzept „Algorithmus“<br />
terminieren, deterministisch und zugleich determiniert sein. So wäre gesichert, das ein<br />
Output nach endlicher Zeit zu erwarten ist, dessen Herleitung nachvollziehbar (weil in<br />
eindeutiger Weise geschehen) und dessen Validität (siehe funktionale Spezifikation)<br />
gesichert. Allerdings muss ein deterministischer Algorithmus nicht unbedingt<br />
determiniert sein. Vielfach ist eine Forderung nach Determiniertheit noch nicht einmal<br />
zweckmäßig (siehe künstliche Intelligenz). Selbst das Kriterium der Terminiertheit ist in<br />
einigen wenigen aber umso bedeutenderen Anwendungsgebieten nicht erfüllbar (siehe<br />
Betriebssystem). Dieser Umstand, dass keine allgemeinen Aussagen über die<br />
Anforderungen bezüglich der Eigenschaften eines Algorithmus getroffen werden<br />
können, schlägt sich in der Literatur insofern nieder, als das die Definitionen bezüglich<br />
konstituierender Merkmale und suffizienter Anforderungen an einen Algorithmus<br />
vielfach einen „defensiven“ Charakter aufweisen.<br />
In diesem Sinne kann ein Algorithmus zusammenfassend also als ein<br />
Problemlösungsverfahren für Probleme einer bestimmten Problemlösungsklasse<br />
betrachtet werden. Hierbei muss er einer funktionalen Spezifikation genügen. Die<br />
Lösungsfindung geschieht in einer Abfolge von elementaren Einzelschritten. Die<br />
algorithmische Darstellung und Beschreibung der Komposition dieser Einzelschritte hat<br />
prinzipiell in einer endlichen, präzisen Beschreibung des Verfahrens unter Verwendung<br />
elementarer Verarbeitungsschritte zu erfolgen.<br />
Neben dieser umgangssprachlichen Annäherung an den Algorithmusbegriff gibt es<br />
weitaus formalere (mathematische) Ansätze zur Beschreibung des algorithmischen<br />
Konzeptes. Beispielsweise ist es auch möglich, für jeden Algorithmus zu fordern, auf<br />
einer so genannten Turing-Maschine ausführbar (turing - berechenbar) zu sein. Eine<br />
Turing-Maschine ist dabei ein abstraktes theoretisches Modell eines Rechners zur<br />
Abarbeitung eines Algorithmus. Ein Algorithmus ist in diesem Sinne also alles, was<br />
eine Turingmaschine ausführen kann.<br />
2.2 Vom Problem zum Algorithmus<br />
Ausgangspunkt eines jeden Algorithmus ist die Formulierung einer Problemstellung (in<br />
Form eines konkreten Problems oder einer Problemklasse). In den meisten Fällen ist die<br />
Problemstellung jedoch sehr allgemein und wenig handhabbar bezüglich einer<br />
strukturierten Lösungsfindung. Sollen beispielsweise zwei Zahlen miteinander addiert<br />
werden, so ist zwar die Problemstellung benannt, jedoch ist noch nicht ersichtlich, wie<br />
7
Kapitel 2: Das Konzept „Algorithmus“<br />
diese Addition erfolgen soll und was in diesem Zusammenhang überhaupt unter einer<br />
Zahl zu verstehen ist.<br />
Es bedarf folglich einer Strukturierung und Formalisierung der Problemsstellung. Dies<br />
geschieht durch eine geeignete Modellierung des Problembereiches [Ah87, S. 1-2].<br />
Solch ein Modell ist meistens sehr präzise formuliert (formales Modell). Auf Grundlage<br />
der Eigenschaften des formalen Modells kann identifiziert werden, was unter einer<br />
„guten“ oder optimalen Lösung zu verstehen ist. Darauf aufbauend ist es jetzt möglich,<br />
eine geeignete Lösungsstrategie zum Auffinden einer guten bzw. optimalen Lösung zu<br />
entwickeln. Eine derartige Strategie (z.B. Durchsuchen des Lösungsraums) ist ebenfalls<br />
abhängig von den Eigenschaften und Annahmen des Modells.<br />
Hier wird deutlich, dass schon die Modellierung des Problembereiches weitreichende<br />
Auswirkungen auf den darauf aufbauenden Algorithmus hat, ist er doch nichts anderes<br />
als die Formalisierung der Lösungsstrategie, eine Lösungsvorschrift also. Im Beispiel<br />
der Addition zweier Zahlen ist die Art der Modellierung einer „Zahl“ durchaus<br />
entscheidend für die Handhabbarkeit und potentielle Effizienz einer Addition: Stelle ich<br />
Zahlen einfach als Striche dar (Unärsystem) oder lege ich die römische<br />
Zahlendarstellung zugrunde? Rechne ich gar mit arabischen Ziffern? Wenn ja, im<br />
Dual-, Oktal- oder Dezimalsystem? (Frage der Modellierung). Wie sieht die erhaltene<br />
Zahl nach der Addition aus und nach welchen Regeln gelange ich zu dieser<br />
Zahlendarstellung? (Frage nach der Lösung des Problems und den Eigenschaften des<br />
Modells). Je nachdem, welches Zahlensystem zugrunde gelegt wird, ist die<br />
Lösungsstrategie eher simpel oder aber sehr aufwendig (z.B. ist die Addition von<br />
Zahlen im Unärsystem sehr leicht im Vergleich zur Addition römischer Zahlen!).<br />
Ist der Problembereich nun hinreichend formalisiert/ modelliert, kann ausgehend von<br />
der Lösungsstrategie ein Algorithmus unter Berücksichtigung der modellspezifischen<br />
Eigenschaften entwickelt werden.<br />
Dieser Prozess wird in Form der so genannten schrittweisen Verfeinerung vollzogen.<br />
Infolge der Verfeinerung durchläuft der Algorithmus verschiedene Abstraktionsstufen.<br />
Dies führt zu einer „Ableitungskette“, in der ausgehend von einer recht abstrakten<br />
Algorithmusskizze nach und nach detailliertere (und damit weniger abstrakte)<br />
algorithmische Beschreibungen abgeleitetet werden. Die Präzision der Beschreibung<br />
nimmt so mit sinkendem Abstraktionsgrad zu. Der Begriff der Abstraktion bezieht sich<br />
hier also auf die Art der Darstellung und der dadurch implizierten „Entfernung“ zur<br />
8
Kapitel 2: Das Konzept „Algorithmus“<br />
konkreten Ausführung auf einer Maschine (dem ausführbaren Programm in Form von<br />
Maschinencode).<br />
Auf der obersten Abstraktionsstufe ist der Algorithmus umgangssprachlich oder<br />
graphisch (Struktogramme, Sequenzdiagramme) formuliert. Schon in diesem Stadium<br />
muss die Formulierung den Anforderungen an algorithmische Beschreibungen genügen,<br />
insbesondere des präzisen Ausdruckes (siehe 2.1). Allerdings wird dies in der Praxis<br />
häufig nicht in dieser strikten Form gehandhabt. Vielmehr wird der Prozess der<br />
schrittweisen Verfeinerung dahingehend interpretiert, als dass die Präzision (und damit<br />
auch der Grad der Eindeutigkeit) der Beschreibung mit abnehmendem<br />
Abstraktionsniveau zu verstärken ist. Die Präzision erfolgt dann häufig erst im<br />
Implementierungsprozess, wenn der Algorithmus in einer konkreten<br />
Programmiersprache formuliert wird.<br />
Im Folgenden soll die schrittweise Verfeinerung mit vorausgehender<br />
„Strategieformulierung und Modellierung“ an einem Beispiel erläutert werden. Die<br />
Problemstellung lautet: „Sortiere eine Menge (unsortierter) ganzer Zahlen aufsteigend“.<br />
Modellierung: Die Menge der ganzen Zahlen wird durch ein Feld (Array)<br />
repräsentiert. Dabei repräsentiert jedes Feldelement eine ganze Zahl und ist über<br />
einen Index zugreifbar.<br />
Eine mögliche Strategie (einfach aber nicht die „effizienteste“): Teile das Feld in<br />
einen sortierten Teil und einen Unsortierten Teil wobei der unsortierte Teil<br />
verkleinert werden soll. Anfangs bestehe der sortierte Teil nur aus dem ersten<br />
Feldelement, der unsortierte aus den übrigen Feldelementen. Für alle Feldelemente<br />
im Array mache folgendes: entferne das erste Element aus dem unsortierten Teil<br />
und durchsuche den sortierten, um es an der korrekten Position einzufügen.<br />
füge ein<br />
1 2 3 5 7 9 < … < … < … 4 8 6<br />
sortiert<br />
unsortiert<br />
Abbildung 2: visualisierte Idee Insertion Sort<br />
Die erste algorithmische Abstraktion im Zuge der schrittweisen Verfeinerung hierzu<br />
ließe sich wie folgt darstellen:<br />
9
Kapitel 2: Das Konzept „Algorithmus“<br />
/*Sortieren eines Arrays durch Einfügen */<br />
// bis Restarray (unsortierter Teil) einelementig<br />
for (int i = 1; i < array.length; i++)<br />
// erstes Element aus unsortiertem Teil auswählen<br />
// Element als „tmp“ zwischenspeichern<br />
// durchlaufe den sortierten Teil in einer<br />
// Schleife von hinten nach vorne<br />
while (sortierter Teil noch nicht durchlaufen und<br />
Feldelement > „tmp“)<br />
// dabei vertausche in jedem Schritt die Inhalte des<br />
// aktuellen Feldelementes mit rechtem benachbarten<br />
// Feldelement<br />
// füge „tmp“ an in das Feldelement ein, das zuletzt<br />
// untersucht wurde<br />
Hier ist schon erkennbar, dass sich die Beschreibung des Algorithmus neben<br />
umgangssprachlichen Formulierungen auch einer formaleren Kontrollstruktursyntax<br />
aus Programmiersprachen bedient. So wird diese Art der Verfeinerung oder<br />
Abstraktion auch als Pseudocode bezeichnet.<br />
In der nächsten Verfeinerung wird dieser Pseudocode nun in die Syntax einer<br />
beliebigen Programmiersprache übersetzt. Der große Vorteil von Pseudocode ist,<br />
dass er von einer konkreten Programmiersprache abstrahiert, dieser aber in der<br />
Regel ohne großen Aufwand in eine beliebige Programmiersprache übersetzt<br />
(„abgeleitet“) werden kann. In diesem Beispiel wird der Pseudocode in die<br />
Programmiersprache Java übersetzt:<br />
/*Sortieren eines Arrays durch Einfügen */<br />
public static void insertionSort(int[] array) {<br />
// bis Restarray (unsortierter Teil) einelementig<br />
for (int i = 1; i < array.length; i++) {<br />
// erstes Element aus unsortiertem Teil auswählen<br />
// Element als „tmp“ zwischenspeichern<br />
int tmp = array[i];<br />
// durchlaufe den sortierten Teil in einer<br />
// Schleife von hinten nach vorne<br />
// Index fuer Durchlauf initialisieren<br />
int j = i - 1;<br />
while ((j >= 0) && (tmp < array[j])) {<br />
// dabei vertausche in jedem Schritt die Inhalte des<br />
// aktuellen Feldelementes mit rechtem benachbarten<br />
// Feldelement<br />
array[j+1] = array[j];<br />
//dekrementiere den Index j<br />
j = j – 1;<br />
}<br />
// füge „tmp“ an in das Feldelement ein, das zuletzt<br />
// untersucht wurde<br />
array[j+1] = tmp;<br />
} }<br />
10
Kapitel 2: Das Konzept „Algorithmus“<br />
Um den Algorithmus maschinell (auf einem Computer) ausführen zu lassen,<br />
überführen wir den in der Programmiersprachensyntax beschriebenen Algorithmus<br />
in ein Programm. Hierzu muss die algorithmische Beschreibung um<br />
programmiersprachenspezifische Beschreibungsmittel und abstrakte Befehle<br />
(Befehle, die unabhängig von einer konkreten Maschine sind), ergänzt werden. Ist<br />
dies geschehen, ergibt sich der so genannte Quellcode. Hier wird auch deutlich, dass<br />
ein Programm nicht mit einem Algorithmus gleichgesetzt werden kann. Vielmehr<br />
stellt es eine notwendige Hülle dar, in welcher durchaus auch mehrere Algorithmen<br />
verpackt sein können. Denkbar sind auch Programme ohne eine konkrete<br />
Algorithmenbeschreibungen oder mit ausschließlich trivialer algorithmischer<br />
Formulierung.<br />
Für das Beispiel wird im Folgenden ein repräsentativer Quellcode aus (jetzt ohne<br />
Kommentare und in Java-Syntax) dargestellt.<br />
public class InsertionSort {<br />
private static int[] array = {13,4,5,2,6,1};<br />
public static void main(String args[]) {<br />
insertionSort(array);<br />
System.out.println(“Ergebnis: ”);<br />
for (int i = 0; i < array.length; i++) {<br />
System.out.println(array + “ ”);<br />
}<br />
}<br />
public static void insertionSort(int[] array) {<br />
for (int i = 1; i < array.length; i++) {<br />
int tmp = array[i];<br />
int j = i - 1;<br />
}<br />
}<br />
}<br />
while ((j >= 0) && (tmp < array[j])) {<br />
array[j+1] = array[j];<br />
j = j – 1;<br />
}<br />
array[j+1] = tmp;<br />
Kurze Erläuterung: das Programm sortiert die vorgegebene Menge {13, 4, 5, 2, 6, 1}<br />
ganzer Zahlen und gibt diese anschließend auf dem Bildschirm aus. Auf die<br />
Möglichkeit der manuellen Eingabe wurde verzichtet, um unnötige Komplexität am<br />
Quellcode zu vermeiden. Schließlich geht es in diesem Beispiel um Anschaulichkeit<br />
11
Kapitel 2: Das Konzept „Algorithmus“<br />
und um das Verständnis für die Abstraktionsstufe „Quellcode“ im Prozess der<br />
schrittweisen Verfeinerung.<br />
Der Quellcode kann für sich genommen noch nicht auf einer konkreten Maschine<br />
ausgeführt werden. Vielmehr muss er in eine Repräsentationsform umgesetzt<br />
werden, die einer Maschine (dem Computer) zugänglich ist. Dazu wird der<br />
Quellcode von einem Compiler der benutzten Programmiersprache in einen<br />
Maschinencode bzw. in Maschinensprache übersetzt. Erst jetzt kann das Programm,<br />
und mit ihm der Algorithmus zum laufen gebracht werden!<br />
Der Maschinencode stellt die niedrigste Abstraktionsstufe dar. Eine algorithmische<br />
Beschreibung in Maschinencode ist jetzt maschinenabhängig, wohingegen eine<br />
Beschreibung in Form von Quellcode nach wie vor von der konkreten Maschine<br />
abstrahiert. In Java kann z.B. ein und derselbe Quellcode in verschiedene<br />
Maschinencodes übersetzt werden. Das compilierte Programm liegt in diesem<br />
Beispiel als „Quasi-Maschinencode“ für die Java-Virtual-Machine vor, dem so<br />
genannten Bytecode. Dieser sei aus Platzgründen nicht an dieser Stelle, sondern im<br />
Anhang A vollständig aufgeführt.<br />
Allerdings ist der Quellcode insoweit spezifischer als ein Pseudocode mit gleicher<br />
Bedeutung, als dass der Quellcode ausschließlich für die Programmiersprache gilt,<br />
in der er formuliert wurde. Soll beispielsweise ein in der Programmiersprache Java<br />
geschriebener Quellcode von einem Compiler für die Programmiersprache C++ in<br />
Maschinencode übersetzt werden, wird dies nicht ohne weiteres gelingen.<br />
Anhand dieses eher simplen Beispiels kann leicht der Eindruck entstehen, das sich<br />
der Prozess der schrittweisen Verfeinerung nur über wenige Verfeinerungsstufen<br />
(in diesem Beispiel zwei Stufen) erstreckt. Typischerweise führt eine schrittweise<br />
Verfeinerung zu deutlich mehr als zwei Ableitungsschritten.<br />
Die Folgende Abbildung soll noch einmal den Entstehungsprozess von Algorithmen<br />
veranschaulichen.<br />
12
Kapitel 2: Das Konzept „Algorithmus“<br />
Modell<br />
Problemstellung<br />
Problemformalisierung<br />
Idee/<br />
Anwendungswissen<br />
trickreiches,<br />
elegantes<br />
Design der<br />
„Programmbeschreibung“/<br />
Problem-<br />
Lösungs-<br />
Wissen<br />
Testen<br />
informeller Algorithmus<br />
schrittweise Verfeinerung<br />
Pseudocode/<br />
abstrakte Datentypen<br />
Programm/<br />
Datenstrukturen<br />
informeller Algorithmus<br />
Optimierung/<br />
Schutz des<br />
Bytecodes<br />
ausführbarer<br />
Maschinencode<br />
Abbildung 3: Entstehungsprozess von Algorithmen<br />
Wie aus der graphischen Darstellung zu erkennen ist, gibt es für eine Problemstellung<br />
oftmals mehrere Algorithmen. Dieser Fakt wird an späterer Stelle ausführlich<br />
aufgegriffen. In der juristischen Frage nach der Schützbarkeit von Algorithmen ist es<br />
mithin von großer Bedeutung, beurteilen zu können, welche Algorithmen überhaupt<br />
eines Schutzes bedürfen. Zumeist sind solche Algorithmen von Interesse, welche<br />
Probleme besonders effizient oder im Vergleich zu anderen Algorithmen, welche<br />
dieselbe Spezifikation besitzen, signifikant besser lösen können.<br />
2.3 Reverse Engineering - vom Maschinencode zum Quellcode<br />
Unter dem Reverse Engineering versteht man das Zurückübersetzen vom schwer<br />
lesbaren Maschinencode in den Quellcode. Es wird realisiert durch die Technik des<br />
Dekompilierens. Dieses Rückübersetzen ist nicht ohne einen gewissen Verlust möglich.<br />
Überdies ist Dekompilieren nur für sehr wenige Programmiersprachen (wie z.B. Java)<br />
auf eine sinnvolle Art und Weise möglich. In Java wird z.B. der Quellcode in den<br />
Bytecode für eine virtuelle Maschine übersetzt. Dieser enthält noch alle relevanten<br />
13
Kapitel 2: Das Konzept „Algorithmus“<br />
Informationen, so dass ein Zurückübersetzen auf eine eindeutige Weise geschehen<br />
kann. Maschinencode dagegen ist nicht eindeutig dekompilierbar, was insbesondere ein<br />
automatisierbares Dekompilieren sehr schwierig, wenn nicht sogar unmöglich macht.<br />
Die Notwendigkeit zum Dekompilieren von Software kann sich aus verschiedenen<br />
Gründen ergeben, z.B. wenn der Quellcode versehentlich gelöscht worden oder verloren<br />
gegangen ist, der Softwarehersteller sein Geschäft nicht mehr fortsetzen und somit das<br />
Produkt nicht weiter unterstützen kann oder aber eine geänderte Anwendungssystem -<br />
Landschaft innerhalb einer Unternehmung Analysen und Anpassungen am Quellcode<br />
erfordern (Interoperabelitätssicherung).<br />
Andererseits kann das Dekompilieren auch zu Spionage nach verwendeten Algorithmen<br />
sowie in der Software abgebildeten Geschäftsgeheimnissen missbraucht werden.<br />
Um Verstößen gegen das Gesetzt gegen unlautern Wettbewerbs (UWG) auch auf<br />
technischer Ebene vorzubeugen und das Ausspionieren von Algorithmen und<br />
Geschäftsgeheimnissen in Software durch Dekompilieren zu erschweren, wurden<br />
Obfuscatoren entwickelt. Diese verfremden („verwaschen“) den Maschinencode, so<br />
dass ein Dekompilieren nur eingeschränkt oder überhaupt nicht mehr möglich ist.<br />
Gerade für die Programmiersprache Java wurde eine Reihe von Obfuscatoren<br />
entwickelt, da der Java-Bytecode relativ unproblematisch dekompiliert werden kann<br />
und ein Ausspionieren von verwendeten Algorithmen sehr leicht ist. Java-Obfuscatoren<br />
zielen auf die Verfremdung des Bytecodes ab.<br />
Gelingt es, einen von einem Obfuscator „verwürfelten“ Bytecode zu dekompilieren, so<br />
ist der Quellcode in der Regel nicht mehr lesbar und weniger aufschlussreich.<br />
Methodennamen und Variablenbezeichnungen sind verfremdet (layout obfuscation)<br />
ebenso wie verwendete Datenstrukturen (data obfuscation). Manchmal wird sogar auch<br />
der Kontrollfluss eines Programms geändert (control obfuscation). In diesem Falle ist<br />
ein direktes Dekompilieren nicht möglich.<br />
In dieser Arbeit wird beispielhaft gezeigt, wie eine Anwendung des Java-Obfuscator<br />
JShrink auf den im Anhang A dargestellten Bytecode wirkt. JShrink arbeitet dabei auf<br />
Bytecodeniveau. Hierbei wurde der mit JShrink verfremdete Bytecode dekompiliert.<br />
Der resultierende Quelltext ist im Anhang B aufgeführt.<br />
14
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
3 Aspekte der Schützbarkeit von Algorithmen<br />
Um die Schutzbedürftigkeit von Algorithmen rechtfertigen zu können, bedarf es der<br />
Untersuchung einiger relevanter Aspekte.<br />
Dazu wird im Folgenden ein erster Brückenschlag zur Jurisdiktion vollzogen sowie eine<br />
kurze Untersuchung angestellt, inwieweit eine juristische Rechtfertigung eines<br />
Algorithmenschutzes wirtschaftsinformatorisch beurteilt werden muss. Anschließend<br />
werden eher technische Argumente angeführt, welche eine Rechtfertigung der<br />
Schützbarkeit von Algorithmen auf der Grundlage einer entsprechenden<br />
Erfindungshöhe sowie Verfeinerungsstufe begründet sehen.<br />
3.1 Urheberrecht und Patentrecht<br />
In der Frage nach der Schützbarkeit von Algorithmen erscheinen zwei Rechtskonzepte<br />
relevant, das Urheberrecht und das Patentrecht, welche unabhängig voneinander laufen<br />
und jeweils unterschiedliche Personengruppen bevorteilen.<br />
3.1.1 Algorithmen und das Patentrecht<br />
Bislang lässt sich zumindest nach dem deutschen und dem europäische Patentrecht<br />
keine Software oder gar Quellcodebeschreibung schützen. Schützbar sei ein Programm<br />
immer nur im Zusammenhang mit einer bestimmt Technik.<br />
Programme gelten nach dieser Auffassung nicht als Technik. Diese Sichtweise ist<br />
jedoch recht veraltet. Etymologisch gesehen ergibt sich die Legitimation, Programme<br />
und im Speziellen von Algorithmen als Technik aufzufassen, sofort. Technik bedeutet<br />
demnach nichts anderes als Kunst, Handwerk, Kunstfertigkeit oder Verfahren zur<br />
Lösung einer Aufgabe [Te99]. Umgangssprachlich wurde der Begriff „Technik“ bisher<br />
immer mit Einrichtungen, welche naturwissenschaftliche Erkenntnisse praktisch nutzbar<br />
machen, assoziiert (insbesondere mit Maschinen). Die Notwendigkeit, Technik auch als<br />
Verfahren zu verstehen, hat sich erst in den letzten Jahrzehnten mit der wachsenden<br />
Bedeutung der Informationsverarbeitung verstärkt herausgebildet.<br />
Würden dennoch Softwarepatente nach dem Vorbild der USA erteilt werden können ist<br />
einzuwenden, dass derartige nur etwas Patente nützen, wenn man sie angreifen und<br />
verteidigen kann. Gerade kleine und mittelgroße Unternehmen können ein steigendes<br />
15
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
Budget für ihre Rechtsabteilungen nicht finanzieren. Patente, einhergehend mit der<br />
Beobachtung der Konkurrenz und dem Ergreifen repressiver als auch präventiver<br />
juristischer Reaktionen sind sehr teuer. Daher sind große Firmen mit ausreichend<br />
finanziellen Mitteln unverhältnismäßig bevorteilt. Sie können ihren<br />
Wettbewerbsvorsprung bis hin zum Monopol ausbauen, Lizenzbedingungen unterliegen<br />
dann mittelfristig keiner Marktregulierung mehr. Hinzu kommt, dass die Chance<br />
jemanden zu verklagen in den USA schon jetzt wesentlich kleiner ist, als selbst<br />
verklagt zu werden. Einige sprechen vom so genannten „Minenfeld der (Software-)<br />
Patente“.<br />
Dieses Phänomen trägt kuriose Früchte. In einem Wettbewerb der Open-Source–<br />
Gemeinde sollte das Programm gewinnen, welches die meisten Patente verletzt. Sieger<br />
war der Entwickler eines Fortschrittbalkens. Zehn Zeilen Code verstießen gegen 18<br />
Patente.<br />
3.1.2 Äquivalenz von Programmen und Schriftwerken<br />
Das Urheberrecht schützt im Gegensatz zum Patentrecht nur das Programm oder die<br />
Software als ganzes. Weder die Idee, noch wesentliche Programmfragmente zu deren<br />
Umsetzung sind über das Urheberrecht als Einzelaspekte schützbar. Die Schützbarkeit<br />
eines Programms über das Urheberrecht stützt sich auf die Prämisse, dass Programme<br />
mit Schriftwerken vergleichbar sind.<br />
Einige Juristen merken in der Frage nach der Äquivalenz von Computerprogrammen zu<br />
Schriftwerken kritisch an, dass Programme im Gegensatz zu literarischen Werken für<br />
Maschinen geschrieben seien und daher von vornherein nicht mit Schriftwerken<br />
vergleichbar sind und somit insbesondere das Urheberrecht in der Sache der<br />
Schützbarkeit von Programmen nicht einschlägig sei. Diese Sichtweise ist aber nur dann<br />
nachvollziehbar, wenn ein Programm bereits auf dem untersten Abstraktionsniveau<br />
spezifiziert wurde (Maschienencode).<br />
Tatsächlich ist die Auffassung, Programme seien für Maschinen geschrieben, nicht<br />
korrekt. Programme sind sehr wohl für Menschen geschrieben. Sie dienen im<br />
Entwicklungsprozess als Diskussionsgrundlage zur Klärung von Implementierungsfragen<br />
und sie kommunizieren die dem Programm zugrunde liegende Idee zu anderen<br />
Projektmitarbeitern, die räumlich getrennt voneinander arbeiten. Programme nehmen so<br />
auch Koordinationsaufgaben war. Programme enthalten wie literarische Werke auch<br />
16
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
Wissen. Überdies stellen sie Information dar, sobald sie das Wissen von anderen<br />
(Projektmitarbeitern) erweitern.<br />
Wissen und Information sind menschliche Phänomene, die einer Maschine nicht<br />
zugänglich sind! Maschinen arbeiten mit Daten. Erst wenn einer konkreten<br />
Datenverarbeitung der Mensch mit seiner Fähigkeit zur Interpretation und ein<br />
Bezugsrahmen (Anwendungskontext) hinzugefügt wird, stellen die Ergebnisse der<br />
Datenverarbeitung Informationen dar, aus denen dann Wissen generiert wird.<br />
Programme und mit ihnen Algorithmen werden für einen konkreten<br />
Anwendungskontext entworfen. Vorraussetzung hierbei ist die menschliche Intention,<br />
ein Problem sinnvoll lösen zu wollen (sinnvoll setzt Interpretation voraus -> nicht<br />
irgendwie) sowie die Sicherstellung der Verwertbarkeit der Ergebnisse (Interpretation<br />
erneut Vorraussetzung für Beurteilung der Verwertbarkeit).<br />
Insofern sind Programme, ebenso wie Schriftwerke, für Menschen geschrieben und<br />
nicht nur für Maschinen! Ebenso ist die Einordnung als Sprachwerk gemäß den weiter<br />
oben aufgeführten Erläuterungen auf allen Abstraktionsstufen einer algorithmischen<br />
Beschreibung insbesondere auf den unteren Ebenen offensichtlich gerechtfertigt (siehe<br />
Umgangs-, Programmier-, Maschinensprache).<br />
Dieser Auffassung folgend, propagieren nun einige Juristen: „Der Unterschied von<br />
Computerprogrammen und Schriftwerken ist nicht allzu groß!“. Allerdings wird hierbei<br />
nicht differenziert genug argumentiert. Das Medium Buch als Informationsträger besitzt<br />
andere Eigenschaften und Einschränkungen als das Medium Hardware, für das<br />
Programme entworfen werden. So besitzt ein Computer im Gegensatz zu einem Buch<br />
„mehrdimensionalen Ressourcenbeschränkungen“, welche die Möglichkeiten der<br />
Informationsrepräsentation einschränken (beim Buch wirkt evtl. nur die maximale<br />
Anzahl an Seiten einschränkend). Bei einem Buch verläuft eine Formulierung<br />
problemlos, sie läuft „auf Anhieb“. Dies ist unter anderem dadurch begründet, dass ein<br />
Buch durchgängig nur eine Abstraktion zur Informationsdarstellung besitzt, nämlich die<br />
der natürlichen Sprache.<br />
Computerhardware erfordert ungleich mehr Aufwand zum „Verfassen“ eines<br />
Quelltextes. Speicherbeschränkungen, maschinenabhängige Beschränkungen von<br />
Repräsentationsmöglichkeiten (z.B. nur ganze Zahlen darstellbar, keine Fliesskomma-<br />
Arithmetik), effiziente Formulierung des Programms (abhängig von unterliegender<br />
Hardware) seien nur beispielhaft erwähnt. All diese Beschränkungen treten<br />
17
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
typischerweise gleichzeitig auf und müssen somit simultan bei der Programmschöpfung<br />
berücksichtigt werden. Dieser Aspekt wird in der Diskussion über die Auswirkung der<br />
Verfeinerungsstufe eines Algorithmus auf deren Schutzbedürftigkeit aufgegriffen.<br />
Demgegenüber ist allen Sprachwerken insbesondere auch den Computerprogrammen<br />
eines gemein: Die eigenschöpferische Leistung ist Voraussetzung für den Anspruch auf<br />
Schutz und die Schätzung des Werkes. Der ideelle Wert von Informationsgehalt und<br />
induziertem Wissen ist besonders betonenswert.<br />
3.2 Einfluss der Erfindungshöhe auf die Schutzbedürftigkeit<br />
In den USA herrscht ein Trend zum Schutz schon ab einer geringen Erfindungshöhe,<br />
begründet durch die generelle Möglichkeit der Patentierbarkeit von<br />
Computerprogrammen, Software oder Geschäftsideen. Diese Praxis impliziert ein<br />
schwerwiegendes Problem: Die Ressource „Basistechnologie/ grundlegende<br />
Algorithmen“ wird knapp. Das Handwerkzeug eines jeden Programmierers würde der<br />
Allgemeinheit über kurz oder lang entrissen. Der prinzipielle Sinn von Programmierung<br />
an sich, nämlich der Realisierung einer maschinellen Ausführung von Algorithmen,<br />
wäre in Frage gestellt. Dies wäre ungefähr so, als patentierte jemand nach und nach die<br />
arithmetische Operatoren +, -, *, /. Jedwedes Rechnen würde dadurch unmittelbar eine<br />
etwaige Rechtsverletzung nach sich ziehen, Rechnen wäre quasi nicht mehr ohne<br />
weiteres möglich, schon gar nicht für jedermann.<br />
In diesem Sinne könnte man jedes Programmstück als Algorithmus ansehen. Diese<br />
Betrachtung impliziert eine geringe Erfindungshöhe.<br />
Daher erscheint es sinnvoll, lediglich überdurchschnittliche Algorithmen schützen zu<br />
lassen. Dies bezieht sich auf den Algorithmen im engeren Sinne, welche sich durch<br />
komplexe Kombinationen von Kontroll- und Datenstrukturen auszeichnen. An dieser<br />
Stelle sei kurz angemerkt, dass Programme demnach auch ohne Algorithmen im<br />
engeren Sinne existieren. Die Überdurchschnittlichkeit von Algorithmen im engeren<br />
Sinne schlägt sich in deren Erfindungshöhe nieder. Die Erfindungshöhe ließe sich<br />
beispielsweise durch die investierte Forschungszeit, den Innovationsbeitrag, die<br />
konzeptionelle Eleganz und vor allem durch die daraus resultierende Effizienz eines<br />
Verfahrens explizieren. Die Güte und die Qualität eines Algorithmus korreliert positiv<br />
mit der Erfindungshöhe eines Algorithmus. Effiziente Algorithmen fallen nicht vom<br />
Himmel, insbesondere ist die Menge der fähigen Algorithmen – Ingenieure<br />
18
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
vergleichsweise gering. So würde ein durch eine überdurchschnittliche Erfindungshöhe<br />
gerechtfertigter Schutz auch die materiellen Aufwendungen sowie die Personellen<br />
Leistungen der Algorithmenerstellung würdigen.<br />
“Algorithms are a sharp knife - it does exactly what it is supposed to do with a<br />
minimum amount of applied effort. Using the wrong algorithm to solve a problem is like<br />
trying to cut a steak with a screwdriver: you may eventually get a digestible result, but<br />
you will expend considerably more effort than necessary, and the result is unlikely to be<br />
aesthetically pleasing” [Co90, S. 16]<br />
So ließe sich das Sortierproblem mit dem so genannten Quicksort-Algorithmus deutlich<br />
schneller (effizienter) Lösen. Die Idee hinter dem Quicksort ist nicht trivial aber<br />
hochgradig elegant und beruht auf einem Prinzip, das schon den Römern geläufig war:<br />
„Divide and Conquer“. Dieser Algorithmus ist im Anhang C dargestellt.<br />
Beispielhaft seien an dieser Stelle auch die Algorithmen für das MP3- und das GIF-<br />
Format erwähnt. Insbesondere dem MP3-Format liegt eine lange Entwicklungszeit<br />
zugrunde. Das Ziel, multimediale Daten (audio, visuell) hochgradig kompakt<br />
abzuspeichern, also Platz zu sparen in diesem Sinne, hat im Ergebnis die multimediale<br />
Welt revolutioniert. Auf einmal war es möglich, mobile Datenträger mit äußerst<br />
beschränktem Speichervorrat (MP3-Player) wirtschaftlich zu vermarkten oder gar MP3-<br />
Dateien relativ effizient via Internet auszutauschen. Daher ist das MP3-Format<br />
konzeptionell hochgradig nicht trivial und sehr kompliziert. Allein schon die<br />
Schwierigkeit, Daten stark zu komprimieren und dabei die Qualität des Originals<br />
beizubehalten und Audio- sowie Videodaten gleichzeitig zu berücksichtigen, bringt<br />
dieses Format an die Grenze des machbaren. Ähnlich verhält es sich mit dem GIF-<br />
Format, welches allerdings nur die Komprimierung von Bilddaten einschließt und im<br />
Bereich des Webdesigns noch weit verbreitet ist.<br />
Das Problem, was sich hier ergibt, ist das Spannungsfeld, welches durch die<br />
Erfindungshöhe und den damit verbundenen persönlichen und wirtschaftlichen<br />
Interessen induziert wird. Algorithmen mit einer niedrigen Erfindungsleistung sollten<br />
allgemeines Gedankengut bleiben, demgegenüber ist großer Erfindergeist schon aus<br />
moralischen und ethischen Gesichtspunkten in gebührendem Maße zu schätzen und<br />
anzuerkennen, ohne dabei jedoch die Gefahr entstehen zu lassen, durch einen Schutz die<br />
Interessen der Allgemeinheit zu vernachlässigen.<br />
19
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
Eine weitere große Schwierigkeit ergibt sich in der Quantifizierung einer<br />
Erfindungshöhe. Ab wann liegt eine triviale Erfindungshöhe vor, ab wann eine<br />
überdurchschnittliche? Was gehört zum Rüstzeug eines jeden Programmierers?<br />
3.3 Abhängigkeit der Schutzbedürftigkeit von der<br />
Verfeinerungsstufe<br />
Aus Abbildung 3 ist erkennbar, dass Ideenreichtum nicht nur bei der Konzeption eines<br />
Algorithmus erforderlich ist, sondern zusätzliche auch bei der Implementierung<br />
(Erstellen des Programms). Hierbei spielen insbesondere auf der Quellcode-Ebene die<br />
Konzeption von abstrakten Datentypen (ADT’s) und eine geeignete Wahl und Nutzung<br />
von Datenstrukturen sowie abstrakten Befehlen eine große Rolle. Besonders wichtig ist<br />
dann die Überprüfung der Gesamtkonzeption mit anschließender Fehlerbeseitigung<br />
auch konzeptioneller Fehler. Dies wird als Testen bezeichnet. Je näher die Abstraktion<br />
an einer konkreten Maschine ist und je umfangreicher die algorithmische Beschreibung,<br />
desto langwieriger und aufwendiger gestaltet sich das Testen und desto wichtiger wird<br />
es.<br />
Somit nimmt der „Wert“ des zusätzlichen Ideenreichtums mit abnehmendem<br />
Abstraktionsniveau der algorithmischen Beschreibung zu, ebenso sind gerade auf den<br />
unteren Abstraktionslevels die spezifischen Fähigkeiten eines Programmierers sehr<br />
stark gefragt (-> Eleganz der Implementierung, „Spagetti-Code“ versus<br />
Wiederverwendbarkeit). Ein guter Algorithmus kann durchaus schlecht implementiert<br />
sein, sogar soweit, dass er die vorgegebene Spezifikation nicht mehr erfüllt (überprüfen<br />
durch Testen!). Dieser Implementierungsaufwand muss honoriert werden in Form von<br />
Schutz oder materieller Entlohnung. Bloße Anerkennung ist hierbei nicht ausreichend,<br />
wird doch sehr viel Arbeitszeit und –kraft in den Implementierungsprozess investiert.<br />
Hier bezieht sich die Schutzbedürftigkeit also auf die Implementierung oder Umsetzung<br />
eines Algorithmus. Eine besondere Schützbedürftigkeit in diesem Sinne bestünde<br />
demnach, wenn die Implementierung außerordentlich elegant und unter effizienter<br />
Ausnutzung der zu Verfügung stehenden Systemressourcen erfolgt ist.<br />
Vielfach ist es auch sinnvoll, eine algorithmische Idee als solche zu schützen, ohne dass<br />
diese schon in einer Programmiersprache implementiert ist. Die Existenz eines<br />
Algorithmus ist unabhängig von dessen Darstellungsform. Sie kann sich in<br />
20
Kapitel 3: Aspekte der Schützbarkeit von Algorithmen<br />
mechanischen Vorrichtungen, Schaltkreisen, Quellcodes oder auch in Pseudocodes<br />
manifestieren.<br />
3.4 Open – Source<br />
Die „Open-Source-Gemeinde“, welche gemeinsam Programme (und damit auch<br />
Algorithmen) entwickelt und diese offen jedermann zur Verfügung stellt, sieht sich<br />
durch Softwarepatente existenziell bedroht. Die Gemeinde befürchtet, speziell durch<br />
Patente in ihrem gestalterischem Potenzial beschnitten zu werden, da ein Schutz gerade<br />
auch bestimmter Algorithmen (siehe Rüstzeug für Programmierer) die Entwicklung von<br />
Programmen für spezifische Anwendungsgebiete (siehe z.B. Text-, Grafikverarbeitung,<br />
Programme mit MP3-Unterstützung) verhindern würde. Die Aufnahme von durch ein<br />
Patent geschützten Programmteile in den eigenen Quellcode verbietet sich schon durch<br />
die Open-Source-Lizenzen, nach denen es jedem Anwender offen steht, den Quellcode<br />
zu kopieren und zu modifizieren, ohne dass dabei Gebühren anfallen.<br />
Auch die Möglichkeit, selbst Softwarepatente anzumelden, entfällt, da die Open-<br />
Source-Gemeinschaft keine gewerbliche Organisation darstellt und somit ein<br />
wesentliches Kriterium für die Patentrechtserteilung nicht erfüllt wird.<br />
Unternehmen mit eigenen Patenten haben zudem mit Open-Source ein besonders<br />
leichtes Spiel, lässt sich doch der quelloffene Code problemlos auf etwaige<br />
Patentrechtsverletzungen überprüfen. Somit wird zugleich das Dekompilierungsverbot<br />
des Urheberrechts umgangen, weil gar nicht erst dekompiliert werden muss.<br />
Open-Source-Software scheint zu Softwarepatenten schlicht inkompatibel zu sein. Das<br />
ist vor allem aber mit der generellen Gegensätzlichkeit von Offenheit zu<br />
Schutzansprüchen zu begründen.<br />
Allerdings zeigt Open-Source (Offener Quellcode) auch eine Möglichkeit auf, wie sich<br />
Softwarepatente aushebeln lassen. Freier Code ist schädlich für ein späteres Patent. Was<br />
es schon gibt, kann nicht patentiert werden, da jeder Anmeldung eine erfinderische<br />
Höhe (Innovation) zugrunde liegen muss. Allerdings impliziert dies jedoch nicht, dass<br />
die Open-Source-Gemeinschaft Algorithmen als solche schützen lassen kann. Streitbar<br />
ist zudem erneut, wie eine erfinderische Höhe bei Software quantifiziert werden kann.<br />
21
Kapitel 4: Fazit<br />
4 Fazit<br />
Möchte man die Frage nach der Schützbarkeit von Algorithmen aus dem juristischen<br />
Blickwinkel heraus untersuchen, lassen sich vorweg schon ein paar Mängel<br />
grundsätzlicher Natur aufzeigen.<br />
So geht z.B. das Patentrecht von einem veralteten Technik-Begriff aus, was bezüglich<br />
der Schützbarkeit von Programmen und Algorithmen im Speziellen von Nachteil ist.<br />
Bezüglich des Urheberrechts lässt sich feststellen, dass eine gewisse Äquivalenz von<br />
Programmen und Schriftwerken gegeben ist. Programme sind wie Schriftwerke auch für<br />
Menschen geschrieben, jedoch existieren auch deutliche Unterschiede hinsichtlich<br />
zusätzlicher Beschränkungen bei der Formulierung von Programmen, welche momentan<br />
in der Rechtssprechung unberücksichtigt bleiben. Darüber hinaus sind Algorithmen<br />
nach deutschem und europäischem Recht weder durch das Urheberrecht schützbar, noch<br />
patentierbar.<br />
Ob ein Algorithmus überhaupt zu schützen ist, sollte eng mit dessen Erfindungshöhe<br />
zusammenhängen. Hierbei ist eine zeit- und kostenintensive Erfindungsleistung, zu der<br />
auch die knappe Ressource Humankapital beigetragen hat, gegenüber trivialen und eher<br />
einfachen Erfindungen zu würdigen. Nicht nur ehrgeiziger Erfindergeist sondern auch<br />
wirtschaftliche Interessen beeinflussen die Erfindungshöhe positiv. Somit wäre ein<br />
Schutz auch aus diesem Blickwinkel heraus für hoch entwickelte Algorithmen<br />
angebracht, um so auch wirtschaftlichen Interessen gerecht zu werden. Zu klären ist bei<br />
dieser Argumentation jedoch, ab welcher Erfindungshöhe eine Schutzbedürftigkeit<br />
gerechtfertigt wäre.<br />
Überdies stellt auch die Verfeinerungsstufe eines Algorithmus ein zentrales Kriterium<br />
zur Bewertung der Schutzbedürftigkeit dar. Die Implementierung eines komplexen<br />
Algorithmus in Form eines Programms ist nicht trivial. Das Problemlösungswissen<br />
eines Programmierers bezüglich einer geschickten und eleganten Implementierung eines<br />
Algorithmus steckt in der Programmformulierung. Je niedriger die Abstraktionsstufe<br />
der algorithmischen Beschreibung, desto „wertvoller“ wird jede Codezeile eines<br />
Programms (Programmformulierung ist zeit- und testintensiv). Vielfach sind schon<br />
Beschreibungen auf relativ hohem Abstraktionsniveau wertvoll (als Ergebnis intensiver<br />
Forschung), so dass es wünschenswert erscheint, einen Algorithmus schon ab einem<br />
hohen Abstraktionsgrad (Algorithmusskizze, Pseudocode) schützen zu können.<br />
22
Anhang A: Bytecode des Beispiels „Insertion Sort“<br />
A Bytecode des Beispiels „Insertion Sort“<br />
Compiled from InsertionSort.java<br />
public class InsertionSort extends java.lang.Object {<br />
public InsertionSort();<br />
public static void main(java.lang.String[]);<br />
public static void insertionSort(int[]);<br />
static {};<br />
}<br />
Method InsertionSort()<br />
0 aload_0<br />
1 invokespecial #1 <br />
4 return<br />
Method void main(java.lang.String[])<br />
0 getstatic #2 <br />
3 invokestatic #3 <br />
6 getstatic #4 <br />
9 ldc #5 <br />
11 invokevirtual #6 <br />
14 iconst_0<br />
15 istore_1<br />
16 goto 51<br />
19 getstatic #4 <br />
22 new #7 <br />
25 dup<br />
26 invokespecial #8 <br />
29 getstatic #2 <br />
32 iload_1<br />
33 iaload<br />
34 invokevirtual #9 <br />
37 ldc #10 <br />
39 invokevirtual #11 <br />
42 invokevirtual #12 <br />
45 invokevirtual #6 <br />
48 iinc 1 1<br />
51 iload_1<br />
52 getstatic #2 <br />
55 arraylength<br />
56 if_icmplt 19<br />
59 return<br />
Method void insertionSort(int[])<br />
0 iconst_1<br />
1 istore_1<br />
2 goto 48<br />
5 aload_0<br />
6 iload_1<br />
7 iaload<br />
8 istore_2<br />
9 iload_1<br />
10 iconst_1<br />
23
Anhang A: Bytecode des Beispiels „Insertion Sort“<br />
11 isub<br />
12 istore_3<br />
13 goto 28<br />
16 aload_0<br />
17 iload_3<br />
18 iconst_1<br />
19 iadd<br />
20 aload_0<br />
21 iload_3<br />
22 iaload<br />
23 iastore<br />
24 iload_3<br />
25 iconst_1<br />
26 isub<br />
27 istore_3<br />
28 iload_3<br />
29 iflt 39<br />
32 iload_2<br />
33 aload_0<br />
34 iload_3<br />
35 iaload<br />
36 if_icmplt 16<br />
39 aload_0<br />
40 iload_3<br />
41 iconst_1<br />
42 iadd<br />
43 iload_2<br />
44 iastore<br />
45 iinc 1 1<br />
48 iload_1<br />
49 aload_0<br />
50 arraylength<br />
51 if_icmplt 5<br />
54 return<br />
Method static {}<br />
0 bipush 6<br />
2 newarray int<br />
4 dup<br />
5 iconst_0<br />
6 bipush 13<br />
8 iastore<br />
9 dup<br />
10 iconst_1<br />
11 iconst_4<br />
12 iastore<br />
13 dup<br />
14 iconst_2<br />
15 iconst_5<br />
16 iastore<br />
17 dup<br />
18 iconst_3<br />
19 iconst_2<br />
20 iastore<br />
21 dup<br />
22 iconst_4<br />
23 bipush 6<br />
25 iastore<br />
26 dup<br />
27 iconst_5<br />
28 iconst_1<br />
29 iastore<br />
30 putstatic #2 <br />
33 return<br />
24
Anhang B: Ergebnis der Anwendung eines Java Obfuscators<br />
B Ergebnis der Anwendung eines Java Obfuscators –<br />
„Insertion Sort“<br />
import I.I;<br />
import java.io.PrintStream;<br />
public class InsertionSort {<br />
private static int append[] = {13, 4, 5, 2, 6, 1};<br />
public InsertionSort() {}<br />
public static final void main(String args[]) {<br />
append(append);<br />
System.out.print(I.I(1));<br />
for(int i = 0; i < append.length; i++)<br />
System.out.print(append[i] + I.I(12));<br />
}<br />
public static final void append(int ai[]) {<br />
for(int i = 1; i < ai.length; i++) {<br />
int j = ai[i];<br />
int k;<br />
for(k = i - 1; k >= 0 && j < ai[k]; k--)<br />
ai[k + 1] = ai[k];<br />
}<br />
}<br />
}<br />
ai[k + 1] = j;<br />
package I;<br />
import java.io.InputStream;<br />
public class I {<br />
static byte getClass[] = null;<br />
static String getResourceAsStream[] = new String[256];<br />
static int intern[] = new int[256];<br />
public I() {}<br />
public static final synchronized String I(int i) {<br />
int j = i & 0xff;<br />
if(intern[j] != i) {<br />
intern[j] = i;<br />
if(i < 0)<br />
i &= 0xffff;<br />
getResourceAsStream[j] = (new String(getClass, 0, i,<br />
getClass[i - 1] & 0xff)).intern();<br />
}<br />
return getResourceAsStream[j];<br />
25
Anhang B: Ergebnis der Anwendung eines Java Obfuscators<br />
}<br />
static {<br />
try {<br />
InputStream inputstream = (new<br />
I()).getClass().getResourceAsStream("" + 'I' + '.' + 'g' + 'i' +<br />
'f');<br />
if(inputstream != null) {<br />
int i = inputstream.read()
Literaturverzeichnis<br />
C Quicksort – Algorithmus<br />
void quicksort(int[] a, int L, int R) {<br />
int m = a[(L+R) / 2];<br />
int i = L;<br />
int j = R;<br />
while(i
Literaturverzeichnis<br />
Literaturverzeichnis<br />
[Ah87]<br />
[Co90]<br />
Alfred V. Aho, John E. Hopcroft, Jefrey D. Ullman: Data structures and<br />
algorithms, Addison-Wesley, 1987.<br />
Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest: Introduction to<br />
Algorithms, The MIT Press, 1990.<br />
[He92] Dietmar Hermann: Algorithmen Arbeitsbuch, Addison-Wesley, 1992.<br />
[Kn73]<br />
[Te99]<br />
Donald E. Knuth: The Art of Computer Programming, 2nd. ed., Addison-<br />
Wesley, 1973.<br />
Rolf A. Teubner: Vorlesungsskript Wirtschaftsinformatik I, Wintersemester<br />
1999/2000<br />
[Wa89] Martin Warnke: Informatik, R. Oldenbourg Verlag, 1989.<br />
[Wi97] Guido Wirtz: Vorlesungsskript Informatik I, Wintersemester 1997/98<br />
28