Von C nach Java, Teil 4: Datenkompression und Verschlüsselung

Seite 4: Komprimierung mit Java

Inhaltsverzeichnis

So viel sei sogleich vorweggenommen: Mit Java 7 ist das Vorhaben mit relativ wenig Aufwand umzusetzen, und das hat mehrere Gründe. Zum einen sind bereits Klassen zur Datenkompression und Verschlüsselung vorhanden, zum anderen wird die programmiertechnische Umsetzung eines solchen Programms in einer hierfür entwickelten Klassenhierarchie übersichtlicher und damit einfacher zu entwickeln, zu erweitern und zu warten. Auch die Verpackung des Programms in eine grafische Oberfläche ist kein Hexenwerk. Das Schönste aber ist: Es ist völlig egal, für welche Plattform das Programm bestimmt ist; lediglich eine Java-Runtime ist auf dem Zielsystem zur Ausführung des Codes erforderlich – einschließlich einer grafischen Oberfläche. Im Folgenden werden die "Eckpfeiler" des Programms in Java vorgestellt, die grafische Oberfläche hierzu beschreibt der nächste Teil dieser Artikelreihe.

Der Ansatz des mit Java entwickelten Beispiels ist anders als der in C. Die Verschlüsselung steht mandatorisch im Vordergrund, während die Datenkompression optional hinzukommt. Die im Projekt verwendeten Klassen fasst das Package net.nieden.FileCrypter zusammen. Die Anwendungsklasse CFileCrypter enthält die main-Methode und sollte sich von einer Kommandozeile aus mit Optionen aufrufen lassen. Gibt man keine Optionen mit auf den Weg, hätte das den Start einer GUI zur Folge. Mit deren Hilfe lassen sich dann Dateien und Optionen vor dem eigentlichen (De-)Kodiervorgang auswählen. Listing 7 zeigt die wesentlichen Methoden der Klasse CFileCrypter.

Die main-Methode ist knapp gehalten. Sollten keine Argumente vorliegen, startet die GUI direkt. Ansonsten wird eine Instanz der Anwendungsklasse erzeugt, der man die Argumente übergibt. Das Durchforsten der Kommandozeile übernimmt der Konstruktor. Prinzipiell passiert dort nicht viel anderes als im C-Beispiel.

Sollten beim Parsen der Kommandozeile Fehler auftreten, wird die Methode usage() aufgerufen. Mit ihr lässt sich auch nachverfolgen, welche Argumente das Programm erwartet beziehungsweise unterstützt – und das sind eine ganze Menge.

Beim Betrachten der Definition der Anwendungsklasse erkennt man, dass sie die Methoden des Interfaces IFileProgressIndicator implementiert. Diese Besonderheit ist dadurch zu erklären, dass die eigentliche (De-)Kodierung der Dateien nicht innerhalb der Anwendungsklasse geschieht, sondern in den eigens dafür vorgesehenen Klassen CFileDecrypter und CFileEncrypter. Sie erhalten die Adresse des besagten Interfaces über speziell dafür vorgesehene Methoden mitgeteilt (cfEncrypter.setProgressIndicator(this)).

Der Code der Anwendungsklasse ist relativ unkompliziert und erklärt sich prinzipiell von selbst. Genauso verhält es sich mit den erwähnten Klassen CFileDecrypter und CfileEncrypter, die im Folgenden kurz beschrieben seien (siehe auch Listing 8).

Der Konstruktor der CFileEncrypter-Klasse nimmt das File-Objekt der Quelldatei, die Blockgröße in KByte und den String mit dem Passwort als Argument. Es werden einige Variablen initialisiert und die Anzahl an zu verarbeitenden Blöcke berechnet. Anschließend wird ein Cipher-Objekt für das Verschlüsseln der Datei angelegt. Hierzu bedient sich das Programm einer statischen Methode (initEncryption()) der Klasse CFileTools.

Ist die Klasse erst einmal erzeugt, lassen sich noch weitere Parameter wie das Setzen des Kompressions-Flags, der Typ der Komprimierung oder das Einschalten von Multithreading für die optimale Ausnutzung der CPU, für das Verschlüsseln und optionale Komprimieren der Quelldatei setzen. Hierzu stehen die letzten fünf Methoden der Klasse zur Verfügung.

Das Handling eines File-Blocks – bei Verwendung mehrerer Threads – obliegt der Klasse CFileBlockProcessor, die die run-Methode des Interfaces Runnable implementiert. Hier werden auch die zuvor beim C-Pendant beschriebenen Synchronisierungsmaßnahmen umgesetzt. Einfacher ist es, wenn kein Multithreading stattfinden soll. Dann werden die statischen Methoden zur Verschlüsselung und Komprimierung eines Blocks direkt aufgerufen. Im Grunde entspricht der gesamte Ablauf dem des C-Programms, deshalb verzichtet der Autor an der Stelle auf eine noch tiefergehende Beschreibung. Das komplette Listing befindet sich zum Nachvollziehen im Download-Verzeichnis.

Der nächste Artikel wird die GUI zum Programm vorstellen und hierbei demonstrieren, wie einfach sich die vorgegebene Dateikompressions-/Verschlüsselungs-Engine in eine GUI integrieren lässt. Zur Abgrenzung zur Sprache C soll nicht verschwiegen werden, dass so ein Vorhaben in C nicht unmöglich ist. Allerdings soll auch klar zum Ausdruck gebracht werden, dass der Aufwand hierzu im Vergleich zum erzielbaren Ergebnis in keinem gesunden Verhältnis mehr steht.

Andreas Nieden
blickt auf fast drei Jahrzehnte an Erfahrung mit Programmiersprachen wie Assembler, C und C++ zurück und ist in den letzten 15 Jahren als Berater im Netzwerk- und Systemmanagement-Umfeld bei Großunternehmen tätig.