02.11.2013 Aufrufe

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

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!