diff --git a/src/main/java/Enigma/model/Codierer.java b/src/main/java/Enigma/model/Codierer.java new file mode 100644 index 0000000000000000000000000000000000000000..dfc7d673e2c8d659177a968a1b1f9576bbc33823 --- /dev/null +++ b/src/main/java/Enigma/model/Codierer.java @@ -0,0 +1,188 @@ +package Enigma.model; + +import org.apache.http.HttpException; + +import java.io.IOException; +import java.sql.SQLException; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Random; + +public class Codierer { + + private String spruchschluessel; + private String kenngruppe; + private String nachricht; + private Hardware hardware; + private Codebuch codebuch; + + public Codierer() { + this.nachricht = ""; + initialisiereHardware(); + } + + /** + * Hier lesen wir den heutigen Eintrag aus dem Codebuch aus und erstellen ein Codebuch Objekt + * Nach dem Codebuch werden dann die Ringe auf die Walzen gesteckt und die Walzen anschließend + * in die Hardware gebaut. + * <p> + * Ein Reflektor wird definiert, jedoch keine Werte zugewisen, da wir nur einen besitzen und + * deshalb alle Einstellungen hierfür Statisch im Reflektor definiert haben. + * <p> + * Das Steck wird ebenfalls definiert und die notwendigen Kabel eingesteckt laut dem heutigen + * Codebuch Eintrag. + */ + private void initialisiereHardware() { + + // Hole den heutigen Eintrag aus der SQLite Datenbank und erstelle daraus ein Codebuch Objekt + try { + this.codebuch = new DatenbankSqlite().getCodebuch(LocalDate.now(ZoneId.of("Europe/Berlin")).getDayOfMonth()); + } catch (SQLException ignored) { + } + + // Das Steckbrett initialisieren + Steckbrett sb = new Steckbrett(); + char[][] verbinder = codebuch.getSteckverbindung(); + // Für jedes Kabel eine Verbindung auf dem Steckbrett setzen + for (char[] kabel : verbinder) { + sb.setzeVertauschung(kabel[0], kabel[1]); + } + + // Die Hardware aus dem Koffer holen (initialisieren) + this.hardware = new Hardware(); + + // Den Ring an der Walze anbringen und die Walze dann in die Hardware einsetzen + hardware.setWalzen(0, codebuch.getWalzenlage()[0], codebuch.getRingstellung()[0]); + hardware.setWalzen(1, codebuch.getWalzenlage()[1], codebuch.getRingstellung()[1]); + hardware.setWalzen(2, codebuch.getWalzenlage()[2], codebuch.getRingstellung()[2]); + + // Der Hardware das gesetzte Steckbrett zuweisen + hardware.setSteckbrett(sb); + + // Ein Reflektor Objekt erstellen und der Hardware bekannt geben + hardware.setReflektor(new Reflektor()); + } + + /** + * Hier wird ein neuer Spruchschlüssel generiert. + * Mit diesem werden die Walzen auf eine neue Startposition gestellt und dem Kopf, mit dem + * Tagesschlüssel codiert, hinzugefügt. + * + * Hierfür wird mittels der Funktion "randomBuchstabe" ein zufälliger Buchstabe generiert, + * und geschaut ob dieser bereits in der globalen Variable this.spruchschluessel vorhanden ist. + * Wenn nicht, wird der Buchstabe dem Spruchschlüssel hinzugefügt. + * + * Dies wir nun so lange gemacht bis der Spruchschlüssel eine länge von drei Zeichen hat. + */ + public void spruchSchluessel() { + while(this.spruchschluessel.length() < 3) { + String temp = this.randomBuchstabe(); + if(!this.spruchschluessel.contains(temp)) { + this.spruchschluessel += temp; + } + } + } + + /** + * Einen zufälligen Buchstaben aus dem Alphabet generieren. + * In der Funktion gibt es den String Alphabet, in welchem alle zulässigen Zeichen eingetragen sind. + * Aus diesem String wird nun zufällig ein Zeichen ausgewählt und zurück gegeben. + * + * @return String : ein zufällig generierter Buchstabe + */ + private String randomBuchstabe() { + Random r = new Random(); + String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char buchstabe = 'X'; + + for (int i = 0; i < alphabet.length(); i++) { + buchstabe = alphabet.charAt(r.nextInt(alphabet.length())); + } + + return String.valueOf(buchstabe); + } + + /** + * Befehl die Nachricht an den Funker zu übergeben + * + * @throws IOException : Die Antwort konnte nicht gelesen werden + * @throws HttpException : Die Nachricht konnte nicht abgesendet werden + */ + public void sendeNachricht() throws IOException, HttpException { + new Funkraum().sendeFunkspruch(new Morsecode().convertBuchstabeToMorsecode(this.nachricht), this.kenngruppe); + } + + /** + * Gibt die letzte empfangene Nachricht zurück + * <p> + * String[0} Tag wann die Nachricht gesendet wurde + * String[1] = Die verschlüsselte Nachricht + * String[2] = Nachricht im Klartext + */ + public String[] empfangeNachricht() { + String[] codierteNachricht = new String[3]; + Morsecode mc = new Morsecode(); + + try { + codierteNachricht = new Funkraum().empfangeFunkspruch(this.kenngruppe); + String morsecode = mc.convertMorsecodeToBuchstabe(codierteNachricht[1]); + String decodiert = ""; + + for (char buchstabe : morsecode.toCharArray()) { + decodiert += this.hardware.codiere(buchstabe); + } + + codierteNachricht[2] = decodiert; + + } catch (IOException e) { + e.printStackTrace(); + } + return codierteNachricht; + } + + /** + * Liest die Kenngruppe aus welche die Maschine gerade besitzt. Früher war dies eine eindeutige Nummer + * die einer Einheit zugewiesen war. Wir hinterlegen hier einen Benutzernamen. + * + * @return String : Kenngruppe + */ + public String getKenngruppe() { + return kenngruppe; + } + + /** + * Setzt die Kenngruppe welche die Enigma gerade benutzt. + * + * @param kenngruppe : String : Kenngruppe welche die Enigma gerade benutzt + */ + public void setKenngruppe(String kenngruppe) { + this.kenngruppe = kenngruppe; + } + + /** + * Gibt die bisher erstellte Nachricht zurück + * + * @return String : Erstellte Nachricht + */ + public String getNachricht() { + return nachricht; + } + + /** + * Gibt das Hardware Objekt zurück + * + * @return Hardware + */ + public Hardware getHardware() { + return hardware; + } + + /** + * Setzt ein neues Hardware Objekt + * + * @param hardware : Hardware + */ + public void setHardware(Hardware hardware) { + this.hardware = hardware; + } +}