Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • d.eisold/enigma
  • Janschubi1993/enigma
  • TsunamiKlaus/enigma
  • alfatrainingkurse/java/enigma
  • FloriN/enigma
  • PaoloPinkel/enigma
6 results
Show changes
Showing
with 1968 additions and 1835 deletions
package enigma;
import enigma.model.Codierer;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.apache.http.HttpException;
import java.io.IOException;
/**
* JavaFX App
*/
public class App extends Application {
/**
* TODO Dokumentieren
*/
private static Scene scene;
private Codierer c;
/**
* TODO Dokumentieren
*
* @param fxml
* @throws IOException
*/
static void setRoot(String fxml) throws IOException {
scene.setRoot(loadFXML(fxml));
}
/**
* TODO Dokumentieren
*
* @param fxml
* @return
* @throws IOException
*/
private static Parent loadFXML(String fxml) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
return fxmlLoader.load();
}
/**
* TODO Dokumentieren
*
* @param args
*/
public static void main(String[] args) {
Application.launch();
}
/**
* TODO Dokumentieren
*
* @param stage
* @throws IOException
*/
@Override
public void start(Stage stage) throws IOException {
scene = new Scene(loadFXML("gui"));
stage.setScene(scene);
stage.show();
this.c = new Codierer();
/**
* TODO: Nur zum Testen muss später wieder gelöscht werden.
*/
//region Test
c.setKenngruppe("deisold");
String nachricht = "Hello world.";
for (char buchstabe : nachricht.toCharArray()) {
if (buchstabe > 0) {
System.out.print(buchstabe + ":");
System.out.print(c.getHardware().codiere(buchstabe));
System.out.println(" W1:" + c.getHardware().getWalzen()[0].getPosition() + " W2:" + c.getHardware().getWalzen()[1].getPosition() + " W3:" + c.getHardware().getWalzen()[2].getPosition());
}
}
try {
System.out.println(c.getNachricht());
c.sendeNachricht();
} catch (HttpException e) {
e.printStackTrace();
}
//endregion
}
}
\ No newline at end of file
package enigma;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.shape.Circle;
import java.util.ArrayList;
public class GuiController {
ArrayList<MenuItem> mItem;
private final static String[] str= {"I", "II", "III", "IV", "V"};
private final static String[] num ={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26"};
private final static String[] bs ={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private String textEingabe="";
@FXML
private Button btnL;
@FXML
private Button btnP;
@FXML
private Button btnY;
@FXML
private Button btnX;
@FXML
private Button btnC;
@FXML
private Button btnV;
@FXML
private Button btnB;
@FXML
private Button btnN;
@FXML
private Button btnM;
@FXML
private Button btnA;
@FXML
private Button btnS;
@FXML
private Button btnD;
@FXML
private Button btnF;
@FXML
private Button btnG;
@FXML
private Button btnH;
@FXML
private Button btnJ;
@FXML
private Button btnK;
@FXML
private Button btnQ;
@FXML
private Button btnW;
@FXML
private Button btnE;
@FXML
private Button btnR;
@FXML
private Button btnT;
@FXML
private Button btnZ;
@FXML
private Button btnU;
@FXML
private Button btnI;
@FXML
private Button btnO;
@FXML
private MenuButton mBtnWalzPos1;
@FXML
private MenuButton mBtnWalzPos3;
@FXML
private MenuButton mBtnWalzPos2;
@FXML
private MenuButton mBtnNotchPos3;
@FXML
private MenuButton mBtnNotchPos2;
@FXML
private MenuButton mBtnStartPos1;
@FXML
private MenuButton mBtnStartPos3;
@FXML
private MenuButton mBtnStartPos2;
@FXML
private TextField tfrein;
@FXML
private TextField tfcodiert;
@FXML
private MenuButton mBtnNotchPos1;
@FXML
private TextField tfStecker1;
@FXML
private TextField tfStecker2;
@FXML
private TextField tfStecker3;
@FXML
private TextField tfStecker4;
@FXML
private TextField tfStecker5;
@FXML
private TextField tfStecker6;
@FXML
private TextField tfStecker7;
@FXML
private TextField tfStecker8;
@FXML
private TextField tfStecker9;
@FXML
private TextField tfStecker10;
@FXML
private Label lblQ;
@FXML
private Label lblE;
@FXML
private Label lblW;
@FXML
private Label lblR;
@FXML
private Label lblT;
@FXML
private Label lblZ;
@FXML
private Label lblO;
@FXML
private Label lblI;
@FXML
private Label lblU;
@FXML
private Label lblA;
@FXML
private Label lblD;
@FXML
private Label lblS;
@FXML
private Label lblF;
@FXML
private Label lblG;
@FXML
private Label lblH;
@FXML
private Label lblK;
@FXML
private Label lblJ;
@FXML
private Label lblP;
@FXML
private Label lblX;
@FXML
private Label lblY;
@FXML
private Label lblC;
@FXML
private Label lblV;
@FXML
private Label lblB;
@FXML
private Label lblL;
@FXML
private Label lblM;
@FXML
private Label lblN;
@FXML
void löschen() {
textEingabe=textEingabe.substring(0,textEingabe.length()-1);
tfrein.setText(textEingabe);
}
@FXML
void btnempfangen() {
}
@FXML
void btnsenden() {
}
/**
* Methode zum setzen des menuButton Textes auf das ausgewählte MenuItem
* @param mb : MenuButton der Walze
* @param mi : MenuItem
*/
private void listener(MenuButton mb, MenuItem mi){
mb.setText(mi.getText());
}
/**
* Methode zur Erstellung der Einträge und Action Listener für die einzelnen Menüs
* @param button : Button für die die Einträge erstellt werden sollen
*/
private void menu(MenuButton button, String[] str) {
mItem = new ArrayList<>();
for (int i = 0; i < str.length; i++) {
//Eintrag aus str der Arraylist mi hinzufügen
mItem.add(new MenuItem(str[i]));
//MenuItem mi dem Button button hinzufügen
button.getItems().add(mItem.get(i));
int finalI = i;
//Listener für die einzelnen Einträge
ArrayList<MenuItem> finalMi = mItem;
mItem.get(i).setOnAction(e -> {
listener(button, finalMi.get(finalI));
});
}
}
@FXML
void initialize() {
//Einträge für Walzen
menu(mBtnWalzPos1, str);
menu(mBtnWalzPos2, str);
menu(mBtnWalzPos3, str);
//Einträge für die Ringe
menu(mBtnNotchPos1, num);
menu(mBtnNotchPos2, num);
menu(mBtnNotchPos3, num);
//Einträge für die Startpositionen
menu(mBtnStartPos1, bs);
menu(mBtnStartPos3, bs);
menu(mBtnStartPos2, bs);
assert tfStecker1 != null : "fx:id=\"tfStecker1\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker2 != null : "fx:id=\"tfStecker2\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker3 != null : "fx:id=\"tfStecker3\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker4 != null : "fx:id=\"tfStecker4\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker5 != null : "fx:id=\"tfStecker5\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker6 != null : "fx:id=\"tfStecker6\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker7 != null : "fx:id=\"tfStecker7\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker8 != null : "fx:id=\"tfStecker8\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker9 != null : "fx:id=\"tfStecker9\" was not injected: check your FXML file 'gui.fxml'.";
assert tfStecker10 != null : "fx:id=\"tfStecker10\" was not injected: check your FXML file 'gui.fxml'.";
assert btnP != null : "fx:id=\"btnP\" was not injected: check your FXML file 'gui.fxml'.";
assert btnY != null : "fx:id=\"btnY\" was not injected: check your FXML file 'gui.fxml'.";
assert btnX != null : "fx:id=\"btnX\" was not injected: check your FXML file 'gui.fxml'.";
assert btnC != null : "fx:id=\"btnC\" was not injected: check your FXML file 'gui.fxml'.";
assert btnV != null : "fx:id=\"btnV\" was not injected: check your FXML file 'gui.fxml'.";
assert btnB != null : "fx:id=\"btnB\" was not injected: check your FXML file 'gui.fxml'.";
assert btnN != null : "fx:id=\"btnN\" was not injected: check your FXML file 'gui.fxml'.";
assert btnM != null : "fx:id=\"btnM\" was not injected: check your FXML file 'gui.fxml'.";
assert btnL != null : "fx:id=\"btnL\" was not injected: check your FXML file 'gui.fxml'.";
assert btnA != null : "fx:id=\"btnA\" was not injected: check your FXML file 'gui.fxml'.";
assert btnS != null : "fx:id=\"btnS\" was not injected: check your FXML file 'gui.fxml'.";
assert btnD != null : "fx:id=\"btnD\" was not injected: check your FXML file 'gui.fxml'.";
assert btnF != null : "fx:id=\"btnF\" was not injected: check your FXML file 'gui.fxml'.";
assert btnG != null : "fx:id=\"btnG\" was not injected: check your FXML file 'gui.fxml'.";
assert btnH != null : "fx:id=\"btnH\" was not injected: check your FXML file 'gui.fxml'.";
assert btnJ != null : "fx:id=\"btnJ\" was not injected: check your FXML file 'gui.fxml'.";
assert btnK != null : "fx:id=\"btnK\" was not injected: check your FXML file 'gui.fxml'.";
assert btnQ != null : "fx:id=\"btnQ\" was not injected: check your FXML file 'gui.fxml'.";
assert btnW != null : "fx:id=\"btnW\" was not injected: check your FXML file 'gui.fxml'.";
assert btnE != null : "fx:id=\"btnE\" was not injected: check your FXML file 'gui.fxml'.";
assert btnR != null : "fx:id=\"btnR\" was not injected: check your FXML file 'gui.fxml'.";
assert btnT != null : "fx:id=\"btnT\" was not injected: check your FXML file 'gui.fxml'.";
assert btnZ != null : "fx:id=\"btnZ\" was not injected: check your FXML file 'gui.fxml'.";
assert btnU != null : "fx:id=\"btnU\" was not injected: check your FXML file 'gui.fxml'.";
assert btnI != null : "fx:id=\"btnI\" was not injected: check your FXML file 'gui.fxml'.";
assert btnO != null : "fx:id=\"btnO\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnWalzPos1 != null : "fx:id=\"mBtnWalzPos1\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnWalzPos3 != null : "fx:id=\"mBtnWalzPos3\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnWalzPos2 != null : "fx:id=\"mBtnWalzPos2\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnNotchPos3 != null : "fx:id=\"mBtnNotchPos3\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnNotchPos2 != null : "fx:id=\"mBtnNotchPos2\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnStartPos1 != null : "fx:id=\"mBtnStartPos1\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnStartPos3 != null : "fx:id=\"mBtnStartPos3\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnStartPos2 != null : "fx:id=\"mBtnStartPos2\" was not injected: check your FXML file 'gui.fxml'.";
assert tfrein != null : "fx:id=\"tfrein\" was not injected: check your FXML file 'gui.fxml'.";
assert tfcodiert != null : "fx:id=\"tfcodiert\" was not injected: check your FXML file 'gui.fxml'.";
assert mBtnNotchPos1 != null : "fx:id=\"mBtnNotchPos1\" was not injected: check your FXML file 'gui.fxml'.";
assert lblQ != null : "fx:id=\"lblQ\" was not injected: check your FXML file 'gui.fxml'.";
assert lblE != null : "fx:id=\"lblE\" was not injected: check your FXML file 'gui.fxml'.";
assert lblW != null : "fx:id=\"lblW\" was not injected: check your FXML file 'gui.fxml'.";
assert lblR != null : "fx:id=\"lblR\" was not injected: check your FXML file 'gui.fxml'.";
assert lblT != null : "fx:id=\"lblT\" was not injected: check your FXML file 'gui.fxml'.";
assert lblZ != null : "fx:id=\"lblZ\" was not injected: check your FXML file 'gui.fxml'.";
assert lblO != null : "fx:id=\"lblO\" was not injected: check your FXML file 'gui.fxml'.";
assert lblI != null : "fx:id=\"lblI\" was not injected: check your FXML file 'gui.fxml'.";
assert lblU != null : "fx:id=\"lblU\" was not injected: check your FXML file 'gui.fxml'.";
assert lblA != null : "fx:id=\"lblA\" was not injected: check your FXML file 'gui.fxml'.";
assert lblD != null : "fx:id=\"lblD\" was not injected: check your FXML file 'gui.fxml'.";
assert lblS != null : "fx:id=\"lblS\" was not injected: check your FXML file 'gui.fxml'.";
assert lblF != null : "fx:id=\"lblF\" was not injected: check your FXML file 'gui.fxml'.";
assert lblG != null : "fx:id=\"lblG\" was not injected: check your FXML file 'gui.fxml'.";
assert lblH != null : "fx:id=\"lblH\" was not injected: check your FXML file 'gui.fxml'.";
assert lblK != null : "fx:id=\"lblK\" was not injected: check your FXML file 'gui.fxml'.";
assert lblJ != null : "fx:id=\"lblJ\" was not injected: check your FXML file 'gui.fxml'.";
assert lblP != null : "fx:id=\"lblP\" was not injected: check your FXML file 'gui.fxml'.";
assert lblX != null : "fx:id=\"lblX\" was not injected: check your FXML file 'gui.fxml'.";
assert lblY != null : "fx:id=\"lblY\" was not injected: check your FXML file 'gui.fxml'.";
assert lblC != null : "fx:id=\"lblC\" was not injected: check your FXML file 'gui.fxml'.";
assert lblV != null : "fx:id=\"lblV\" was not injected: check your FXML file 'gui.fxml'.";
assert lblB != null : "fx:id=\"lblB\" was not injected: check your FXML file 'gui.fxml'.";
assert lblL != null : "fx:id=\"lblL\" was not injected: check your FXML file 'gui.fxml'.";
assert lblM != null : "fx:id=\"lblM\" was not injected: check your FXML file 'gui.fxml'.";
assert lblN != null : "fx:id=\"lblN\" was not injected: check your FXML file 'gui.fxml'.";
leuchten(btnA, lblA);
leuchten(btnB, lblB);
leuchten(btnC,lblC);
leuchten(btnD, lblD);
leuchten(btnE, lblE);
leuchten(btnF, lblF);
leuchten(btnG, lblG);
leuchten(btnH, lblH);
leuchten(btnI, lblI);
leuchten(btnJ,lblJ);
leuchten(btnK, lblK);
leuchten(btnL, lblL);
leuchten(btnM, lblM);
leuchten(btnN, lblN);
leuchten(btnO, lblO);
leuchten(btnP, lblP);
leuchten(btnQ,lblQ);
leuchten(btnR, lblR);
leuchten(btnS, lblS);
leuchten(btnT, lblT);
leuchten(btnU, lblU);
leuchten(btnV, lblV);
leuchten(btnW, lblW);
leuchten(btnX,lblX);
leuchten(btnY, lblY);
leuchten(btnZ, lblZ);
leuchtencirc(btnA,circ);
}
@FXML
private Button Q;
/**
* Auswertung welcher Button gedrückt wurde
* @param e => ActionEvent des auslösenden Button
*/
@FXML
private void gedrueckteTaste(ActionEvent e) {
//TODO Anbindung an Klasse Hardware
if (e.getSource() == btnA) setText(btnA);
if (e.getSource() == btnB) setText(btnB);
if (e.getSource() == btnC) setText(btnC);
if (e.getSource() == btnD) setText(btnD);
if (e.getSource() == btnE) setText(btnE);
if (e.getSource() == btnF) setText(btnF);
if (e.getSource() == btnG) setText(btnG);
if (e.getSource() == btnH) setText(btnH);
if (e.getSource() == btnI) setText(btnI);
if (e.getSource() == btnJ) setText(btnJ);
if (e.getSource() == btnK) setText(btnK);
if (e.getSource() == btnL) setText(btnL);
if (e.getSource() == btnM) setText(btnM);
if (e.getSource() == btnN) setText(btnN);
if (e.getSource() == btnO) setText(btnO);
if (e.getSource() == btnP) setText(btnP);
if (e.getSource() == btnQ) setText(btnQ);
if (e.getSource() == btnR) setText(btnR);
if (e.getSource() == btnS) setText(btnS);
if (e.getSource() == btnT) setText(btnT);
if (e.getSource() == btnU) setText(btnU);
if (e.getSource() == btnV) setText(btnV);
if (e.getSource() == btnW) setText(btnW);
if (e.getSource() == btnX) setText(btnX);
if (e.getSource() == btnY) setText(btnY);
if (e.getSource() == btnZ) setText(btnZ);
if (e.getSource()==Q) setText(Q);
}
/**
* schreibt Buchstaben des gedrückten Knopfes in Textfeld tfrein
* @param b : gedrückter Knopf
*/
private void setText(Button b){
if (textEingabe.length()<250) {
textEingabe += b.getText();
tfrein.setText(textEingabe);
}
}
@FXML
private Circle circ;
private void leuchtencirc(Button taste, Circle leuchte){
taste.setOnMousePressed(mouseEvent -> {
leuchte.setStyle("-fx-fill: #FFA500");
});
taste.setOnMouseReleased(mouseEvent -> {
leuchte.setStyle("-fx-background-color: "+ taste.getBackground());
leuchte.setStyle("-fx-border-color: #000000");
});
}
private void leuchten(Button taste, Label leuchte){
taste.setOnMousePressed(mouseEvent -> {
leuchte.setStyle("-fx-background-color: #FFA500");
});
taste.setOnMouseReleased(mouseEvent -> {
leuchte.setStyle("-fx-background-color: "+ taste.getBackground());
// leuchte.setStyle("-fx-border-color: #000000");
});
}
/**
* Setzt die Anzeige des entsprechende Gui-Element auf die entsprechende Walze
* ->d.h. welche Walze sitzt auf welcher Position
*
* @param walze => gibt die Walzennummer an (entspricht
* @param position => gibt die Position der Walze (entspricht
*/
public void setzeWalze(int walze, int position){
switch (position){
case 1:
mBtnWalzPos1.setText(str[position]);
break;
case 2:
mBtnWalzPos2.setText(str[position]);
break;
case 3:
mBtnWalzPos3.setText(str[position]);
break;
default:
break;
}
}
/**
* Setzt den Notch (position)=> die Mitnahmeposition der Walze (walze) fest
* Mitnahmeposition meint => die nächste Walze wird bei erreichen dieser Position (notch)
* um eine Stelle versetzt
*
* @param walze => gibt die walze an
* @param position => gibt den notch der Walze (walze) an
*/
public void setzeRing(int walze, int position){
switch (walze){
case 1:
mBtnNotchPos1.setText(num[position]);
break;
case 2:
mBtnNotchPos2.setText(num[position]);
break;
case 3:
mBtnNotchPos3.setText(num[position]);
break;
default:
break;
}
}
/**
* Setzt die Startposition/ aktuelle Position der Walze
* @param walze => gibt die walze an
* @param buchstabe gibt den Startwert bzw die aktuelle Position der Walze (walze) an
*/
public void setzePosition(int walze, char buchstabe){
switch (walze){
case 1:
mBtnStartPos1.setText(String.valueOf(buchstabe));
break;
case 2:
mBtnStartPos2.setText(buchstabe+"");
break;
case 3:
mBtnStartPos3.setText(buchstabe+"");
break;
default:
break;
}
}
/**
* Setzt den aktuellen TagesSchluessel
* @param tagesSchluessel
*/
public void setzeTagesSchluessel(String tagesSchluessel){
//TODO Benötige TestString aus der DB Codebuch
}
}
package enigma;
import java.io.IOException;
import javafx.fxml.FXML;
public class KenngruppeController {
@FXML
private void switchToPrimary() throws IOException {
App.setRoot("gui");
}
}
\ No newline at end of file
package enigma;
import java.sql.SQLException;
public class Main {
public static void main(String[] args) throws SQLException {
App.main(args);
}
}
package enigma.database;
import enigma.model.Codebuch;
import java.sql.*;
/**
* Dies ist die SQLite Datenbank Klasse
* In der SQLite Datei im Resources Ordner liegt das Codebuch welches benötigt wird um die
* Nachrichten mit der Enigma zu ver/entschlüsseln.
* Die Datenbank ist statisch und deshalb konnte sie im Resources Ordner hinterlegt werden.
* Für jeden Tag des Monats (1-31) ist ein eigener Eintrag enthalten welcher über die Funktion
* getCodebuch abgerufen werden kann.
* Zurückgegeben wird ein Array welcher in der getCodebuch Funktion genauer dokumentiert ist.
*/
public class DatenbankSqlite {
/**
* Verbindung zur SQLite Datenbank aufbauen.
* Die Datei liegt in den Resources und ändert sich nicht,
* weshalb der Pfad zu derselben fest hinterlegt ist.
*
* @return conn : Connection
*/
private Connection connect() {
String url = "jdbc:sqlite::resource:enigma/codebuch.sqlite";
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* Liest das Codebuch aus der SQLite Datenbank aus
* Dieser Funktion muss ein tag als int Wert übergeben werden.
* Anschließend wir eine Verbindung zur SQLite Datenbank aufgebaut und das Codebuch angefragt.
* Dieses wird in ein Object vom Type Codebuch gepackt und zurück gegeben.
*
* @param tag : int : Tag für welchen ein Codebuch benötigt wird.
* @return Codebuch : Codebuch Object mit dem Codebuch des angefragten Tages
*/
public Codebuch getCodebuch(int tag) throws SQLException {
Codebuch cb = new Codebuch();
Connection conn = this.connect();
PreparedStatement pstm = conn.prepareStatement("SELECT * FROM table_codebuch WHERE Tag=? LIMIT 1");
pstm.setInt(1, tag);
ResultSet rs = pstm.executeQuery();
String[] walzenlage, ringstellung, steckverbindung;
while (rs.next()) {
cb.setTag(rs.getInt("Tag"));
walzenlage = rs.getString("Walzenlage").split(",");
for (int i = 0; i < 3; i++) {
cb.setWalzenlage(i, Integer.parseInt(walzenlage[i]));
}
ringstellung = rs.getString("Ringstellung").split(",");
for (int i = 0; i < 3; i++) {
cb.setRingstellung(i, Integer.parseInt(ringstellung[i]));
}
cb.setSteckverbindung(rs.getString("Steckverbindung").split(","));
}
return cb;
}
//region Random New Codebuch generieren
/**
* Setzt zufällige Codebuch Einträge in die SQLite Datenbank
* Tag => int
* Walzenlage => String w1,w2,w3
* Ringstellung => String r1,r2,r3
* Steckverbindungen => s0,s1,s2,s3,s4,s5,s6,s7,s8,s9
*/
/*
public void autoGenCodebuch() throws SQLException {
Connection conn = connect();
conn.setAutoCommit(false);
PreparedStatement pstmtInsert = conn.prepareStatement("INSERT INTO table_codebuch (Tag, Walzenlage, Ringstellung, Steckverbindung) VALUES (?, ?, ?, ?);");
for (int i = 3; i < 32; i++) {
pstmtInsert.setInt(1, i);
pstmtInsert.setString(2, walzenlage());
pstmtInsert.setString(3, ringstellung());
pstmtInsert.setString(4, steckverbindung());
pstmtInsert.executeUpdate();
}
conn.commit();
}
/**
* Generiert einen String aus 3 Zufalls-Zahlen(zwischen 1 und 5)
* die Zahlen sind durch Komma getrennt
* @return String => walzenlage mit drei Kommaseparierten Zufallszahlen zwischen 1 und 5
*/
/*
private static String walzenlage(){
String walzenlage;
Random random = new Random();
int[] w = new int[3];
for (int i = 0; i < 3; i++) {
w[i] = (random.nextInt(5))+1;
if (i==1&&w[0]==w[i])w[i]=(random.nextInt(5))+1;
if ((i==2&&w[0]==w[2])||(i==2&&w[1]==w[i]))w[i]=(random.nextInt(5))+1;
}
walzenlage= w[0]+","+w[1]+","+w[2];
return walzenlage;
}*/
/**
* Generiert einen String aus 3 Zufalls-Zahlen(zwischen 1 und 26)
* die Zahlen sind durch Komma getrennt
* @return String => ringstellung mit drei Kommaseparierten Zufallszahlen zwischen 1 und 26
*/
/*
private static String ringstellung(){
String ringstellung;
Random random = new Random();
int[] w = new int[3];
for (int i = 0; i < 3; i++) {
w[i] = (random.nextInt(26))+1;
}
ringstellung= w[0]+","+w[1]+","+w[2];
return ringstellung;
}*/
/**
* Generiert einen String aus 10 * 2 unterschiedlichen Großbuchstaben
* @return String => 10 Buchstabenkombinationen mit Komma getrennt
*//*
private static String steckverbindung(){
Random rnd = new Random();
String steckverbindung="";
char[] c = new char[20];
for (int i = 0; i < 20; i++) {
c[i] = (char) (rnd.nextInt(26) + 'A');
for (int j = i; j >= 0; j--) {
if (i>j) {
while (c[i]==c[j]) {
c[i] = (char) (rnd.nextInt(26) + 'A');
j= i-1;
}
}
}
}
steckverbindung = ((""+c[0]) + (""+c[1]) +"," +(""+c[2]) +(""+c[3]) + ","+(""+c[4]) +(""+c[5]) + ","+(""+c[6]) +(""+c[7]) + ","
+(""+c[8]) +(""+c[9]) + ","+(""+c[10]) +(""+c[11]) + ","+(""+c[12]) +(""+c[13]) + ","+(""+c[14]) +(""+c[15]) + ","+(""+c[16]) +(""+c[17]) + ","
+(""+c[18]) +(""+c[19]));
// System.out.println(steckverbindung);
// steckverbindung= (String) steckverbindung.subSequence(0,steckverbindung.lastIndexOf(","));
return steckverbindung;
}*/
//endregion
}
package enigma.model;
import enigma.database.DatenbankSqlite;
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;
/**
* TODO Dokumentieren
*/
public class Codierer {
/**
* TODO Dokumentieren
*/
private String spruchschluessel;
private String kenngruppe;
private String nachricht;
private Hardware hardware;
private Codebuch codebuch;
/**
* TODO Dokumentieren
*/
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.
* <br>
* Ein Reflektor wird definiert, jedoch keine Werte zugewisen, da wir nur einen besitzen und
* deshalb alle Einstellungen hierfür Statisch im Reflektor definiert haben.
* <br>
* 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.
* <p>
* 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.
* <p>
* 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() {
return String.valueOf((char) ('A' + new Random().nextInt(26)));
}
/**
* 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
* <br>
* 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]);
StringBuilder decodiert = new StringBuilder();
for (char buchstabe : morsecode.toCharArray()) {
decodiert.append(this.hardware.codiere(buchstabe));
}
codierteNachricht[2] = decodiert.toString();
} 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;
}
}
package enigma.model;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* Hier sitzt der Funker
* Der Funkraum kann Funksprüche empfangen und senden.
* Hierfür wird eine Verbindung zu einem externen Service aufgebaut.
* Dieser Servive erwartet die Nachrichten im JSON Format. Dazu wird ein k als Kenngruppe
* (Benutzername) übergeben und falls eine Nachricht gesendet werden soll, zusätzlich ein m mit der Nachricht.
* Beides wird als String gesendet.
*/
public class Funkraum {
/**
* Zum Empfangen liefert der Server, anstatt der Kenngruppe (k) den Empfangstag der Nachricht mit damit man
* die Grundeinstellungen aus dem Codebuch, für diesen Tag, raussuchen kann.
* {'m': 'Hello world', 't': '26'}
*
* @param kenngruppe : String : Kenngruppe dieser Engiam
* @return String[] : String Array wobei Index 0 dem Empfangstag entspricht und index 1 der empfangenen Nachricht
* @throws IOException : Exception : wenn keine Verbindung zum Funker aufgebaut werden konnte.
*/
public String[] empfangeFunkspruch(String kenngruppe) throws IOException {
String[] funkspruch = new String[2];
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://enigma.itstall.de/");
// Anfrage Parameter und Encoding setzen
List<NameValuePair> params = new ArrayList<>(2);
params.add(new BasicNameValuePair("k", kenngruppe));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// POST Request ausführen und Rückgabe verarbeiten
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
JSONObject result = new JSONObject(reader.readLine());
if(!result.getString("m").isEmpty()) {
funkspruch[0] = result.getString("t");
funkspruch[1] = result.getString("m");
}
}
return funkspruch;
}
/**
* Dem Service senden wir unsere Nachricht als POST Parameter (m) und unsere Kenngruppe (k).
* Dieser nimmt die Daten entgegeb und hierlerlegt sie auf seinem Stapel (Datenbank) von dem die Nachrichten
* irgendwann, auf Anfrage, wieder abgerufen werden können.
*
* Darauf antworter der Server dann mit einem JSON Object in dem das Ergebnis der Anfrage zu sehen ist.
* {'result': 200}
*
* Die 200 heißt hier das alles erfolgreich durchgeführt werden konnte. Steht hier etwas anderes, ist ein Fehler
* aufgetreten und die Anfrage war nicht erfolgreich.
* In letzterem Fall sollte eine Meldung an den Benutzer ausgegeben werden und ggF später erneut versucht.
*
* @param funkspruch : String : Der zu sendede Funkspruch
* @param kenngruppe : String : Die Kenngruppe dieser Engima
* @throws IOException : Exception : Funkspruch konnte nicht gesendet werden
*/
public void sendeFunkspruch(String funkspruch, String kenngruppe) throws HttpException, IOException {
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://enigma.itstall.de/");
// Anfrage Parameter und Encoding setzen
List<NameValuePair> params = new ArrayList<>(2);
params.add(new BasicNameValuePair("k", kenngruppe));
params.add(new BasicNameValuePair("m", funkspruch));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// POST Request ausführen und Rückgabe verarbeiten
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
JSONObject result = new JSONObject(reader.readLine());
if(result.getInt("result") != 200) {
throw new HttpException("Der andere Funker mag deine Nachricht nicht. Rüge ihn wenn du ihn wieder siehst...");
}
}
}
}
package enigma.model;
/**
* In dieser Klasse wird die Hardware zusammen gefasst.
* Alle Komponenter der Enigma laufen hier zusammen.
*
* <p>
* walzen : Walze[] : Ist ein Array der drei eingebauten Walzen Objekte
* steckbrett : Steckbrett : Das Steckbrett mit den Verbindungen aus dem Codebuch
* reflektor : Reflektor : Dies ist das Objekt der Reflektors
* nachricht : String : Die verschlüsselte Nachricht wird in diesem String zusammen gesetzt und gespeichert
* kenngruppe : String : Früher definierte die Kennzeichnung die Einheit welche diese Enigma benutzte.
* Wir missbrauchen die Kenngruppe für einen Benutzernamen
* </p>
*/
public class Hardware {
/**
* TODO Dokumentieren
*/
private Walze[] walzen;
private Steckbrett steckbrett;
private Reflektor reflektor;
/**
* Im Konstruktor legen wir die Anzahl der Walzen fest welche die Hardware aufnehmen kann.
* Die Enigma I welche hier nachgebildet werden soll, konnte drei Walzen aufnehmen.
*/
public Hardware() {
this.walzen = new Walze[3];
}
/**
* Setzt eine Walze ein
*
* @param walze : int : Setzt die Walze mit der angegebenen Nummer ein
* @param walzenNr : int : Die Nummer der einzusetzenden Walze
*/
public void setzeWalzenNr(int walze, int walzenNr, int ringstellung) {
this.walzen[walze] = new Walze(walzenNr, ringstellung);
}
/**
* Setzt den Notch der Walze
*
* @param walze : int : Position der Walze
* @param position : int : Umspringpunkt auf der Walze
*/
public void setzeRing(int walze, int position) {
this.walzen[walze].setRingstellung(position);
}
/**
* Setzt den Startwert (position) der Walze (walze)
*
* @param walze : int : Nummer der Walze
* @param buchstabe : char : Buchstabe der zugewiesen soll
*/
public void setzePosition(int walze, char buchstabe) {
this.walzen[walze].setPosition(buchstabe);
}
/**
* Verschlüsselt den übergebenen Buchstaben und fügt ihn der Nachricht hinzu
*
* @param buchstabe char : Der zu ver/entschlüsselnde Buchstabe
* @return char : Der ver/entschlüsselte Buchstabe
*/
public char codiere(char buchstabe) {
this.dreheWalzen();
buchstabe = this.steckbrett.codiere(Character.toUpperCase(buchstabe));
buchstabe = this.walzen[2].codiere(buchstabe);
buchstabe = this.walzen[1].codiere(buchstabe);
buchstabe = this.walzen[0].codiere(buchstabe);
buchstabe = this.reflektor.codiere(buchstabe);
buchstabe = this.walzen[0].codiere2(buchstabe);
buchstabe = this.walzen[1].codiere2(buchstabe);
buchstabe = this.walzen[2].codiere2(buchstabe);
buchstabe = this.steckbrett.codiere(buchstabe);
return buchstabe;
}
/**
* Nach jeder codierung eines Buchstabens müssen die Walzen gedreht werden.
* Hier überprüfen wir welche der Walzen gedreht werden müssen und stoßen die Vorgang an.
*/
private void dreheWalzen() {
if (this.walzen[2].dreheWalze()) {
if (this.walzen[1].dreheWalze()) {
this.walzen[0].dreheWalze();
}
}
}
/**
* Gibt die verbauten Walzen Objekte zurück
*
* @return Walze[] : Array mit den Walzen Objekten
*/
public Walze[] getWalzen() {
return this.walzen;
}
/**
* Setzt eine Walze ein und speichert das Objekt im Walzen Array
*
* @param position : int : Position der Walze
* @param walze : int : Die Nummer der Walze
* @param ringstellung : int : Umsprung Punkt der Walze
*/
public void setWalzen(int position, int walze, int ringstellung) {
this.walzen[position] = new Walze(walze, ringstellung);
}
/**
* Gibt das Objekt des Steckbretts zurück
*
* @return Steckbrett : Das eingesetzte Steckbrett mit seinen Kabeln wenn eingesteckt
*/
public Steckbrett getSteckbrett() {
return steckbrett;
}
/**
* Setzt das übergebene Steckbrett Objekt in die Hardware ein
*
* @param steckbrett : Steckbrett : Objekt des Steckbretts mit allen verbundenen Kabeln
*/
public void setSteckbrett(Steckbrett steckbrett) {
this.steckbrett = steckbrett;
}
/**
* Liest den Reflektor aus und gibt ihn zurück
*
* @return Reflektor : Objekt des Reflektors
*/
public Reflektor getReflektor() {
return reflektor;
}
/**
* Setzt den Reflektor ein.
* In der Enigma I welche hier nachgebaut wird, gab es nur einen Reflektor.
* Spätere Versionen haten zwei oder mehr, deshalb haben wir hier auch schon ein Objekt dafür erstellt,
* welches ausgetauscht werden kann.
*
* @param reflektor : Reflektor : Das Obejtk des Reflektors
*/
public void setReflektor(Reflektor reflektor) {
this.reflektor = reflektor;
}
/**
* Diese Funktion setzt die Walzen auf ihren Anfangswert zurück.
* Hierfür ist der Buchstabe "A" festgelegt.
* Dies wird benötigt um zB einen neuen Spruchschlüssel einzustellen oder eine neue Nachricht zu verfassen.
*/
public void resetWalzen() {
this.getWalzen()[0].setPosition('A');
this.getWalzen()[1].setPosition('A');
this.getWalzen()[2].setPosition('A');
}
}
package enigma.model;
import java.util.*;
import java.util.Map.Entry;
/**
* Diese Klasse definiert die Zugehörigkeit zwischen den Buchstaben A-Z und dem zugehörigen Morsecode.
* Die Funktionen sollen Texte von und zu Morsecode konvertieren.
*/
public class Morsecode {
// Anlegen der codeMap als TreeMap
private TreeMap<String, String> codeMap = new TreeMap<>();
/**
* Im Konstruktor werden alle verfügbaren Buchstaben (A-Z) und deren zugehörigen
* Morsecodes, der codeMap hinzugefügt.
*/
public Morsecode() {
this.codeMap.put("A", ".-");
this.codeMap.put("B", "-...");
this.codeMap.put("C", "-.-.");
this.codeMap.put("D", "-..");
this.codeMap.put("E", ".");
this.codeMap.put("F", "..-.");
this.codeMap.put("G", "--.");
this.codeMap.put("H", "....");
this.codeMap.put("I", "..");
this.codeMap.put("J", ".---");
this.codeMap.put("K", "-.-");
this.codeMap.put("L", ".-..");
this.codeMap.put("M", "--");
this.codeMap.put("N", "-.");
this.codeMap.put("O", "---");
this.codeMap.put("P", ".--.");
this.codeMap.put("Q", "--.-");
this.codeMap.put("R", ".-.");
this.codeMap.put("S", "...");
this.codeMap.put("T", "-");
this.codeMap.put("U", "..-");
this.codeMap.put("V", "...-");
this.codeMap.put("W", ".--");
this.codeMap.put("X", "-..-");
this.codeMap.put("Y", "-.--");
this.codeMap.put("Z", "--..");
this.codeMap.put(" ", "-...-");
this.codeMap.put("1", ".----");
this.codeMap.put("2", ".----");
this.codeMap.put("3", "...--");
this.codeMap.put("4", "....-");
this.codeMap.put("5", ".....");
this.codeMap.put("6", "-....");
this.codeMap.put("7", "--...");
this.codeMap.put("8", "---..");
this.codeMap.put("9", "----.");
this.codeMap.put("0", "-----");
}
/**
* Diese Funktion überprüft ob das übergebene Buchstabe in der codeMap enthalten ist.
* Wenn es enthalten ist, wird der zugehörige Morsecode zurück gegeben, ansonsten null
*
* @param buchstabe : char : Zu übersetzender Buchstabe
* @return : String : Das zugehöriger Morsecode aus der codeMap
*/
private String getMorsecode(char buchstabe) {
// Testen ob das Char in der codeMap enthalten ist. Wenn ja, raussuchen und zurück geben
return this.codeMap.getOrDefault(String.valueOf(buchstabe).toUpperCase(), null);
}
/**
* Der übergebene String wird in seine einzelnen Zeichen (char) zerlegt und an die Funktion getMorsecode
* übergeben und der zugehörige Morsecode raus gesucht.
* Mittels eines StringBuilders werden die Ergebnisse zu einem Rückgabe String zusammen gesetzt.
* Wenn kein zugehöriger Code in der codeMap gefunden wurde, wird das Zeichen ignoriert da es bei der
* Enigma nicht vorhanden war.
*
* @param input : String : Zu konventierender Text
* @return String : Die in Morsecode konvertierte Text
*/
public String convertBuchstabeToMorsecode(String input) {
StringBuilder sb = new StringBuilder();
String morsecode;
// Durch alle char im übergebenen String loopen
for(int i = 0; i < input.length(); i++) {
// Wenn der char in der codeMap enthalten ist, an den Rückgabe String anheften, ansonsten nichts ignorieren.
morsecode = this.getMorsecode(input.charAt(i));
if(morsecode != null) {
sb.append(morsecode).append(' ');
}
}
// Gibt den konvertierten String zurück
return sb.toString();
}
/**
* Diese Funktion überprüft ob der übergebene Morsecode in der codeMap enthalten ist.
* Wenn er enthalten ist, wird der zugehörige Buchstabe zurück gegeben, ansonsten null
*
* @param morsecode : String : Der zu übersetzende Morsecode
* @return : String : Das zugehöriger Buchstaben aus der this.codeMap
*/
private String getBuchstabe(String morsecode) {
// Initialisieren des Rückgabe Strings
String result = null;
// Loopt duch die Codemap und erstellt daraus ein Set
for(Entry<String, String> entry : this.codeMap.entrySet()) {
// Wenn Value dem Morsecode entspricht, haben wir unseren Buchstaben gefunden und setzen ihn als Result
if(entry.getValue().equals(morsecode)) {
result = entry.getKey();
}
}
return result;
}
/**
* Der übergebene String wird in einen String Array zerlegt. Als Trennzeichen wird das Leerzeichen genutzt.
* Anschließend wird der Array durchlaufen und die Elemente an die Funktion getBuchstabe übergeben um den
* zugehörigen Buchstaben zu erhalten.
* Mittels eines StringBuilders werden die Ergebnisse zu einem Rückgabe String zusammen gesetzt.
* Wenn kein zugehöriger Buchstabe in der codeMap gefunden wurde, wird das Zeichen ignoriert da es bei der
* Enigma nicht vorhanden war.
*
* @param input : String : Zu konventierender Morsecode
* @return String : Der in Text konvertierte Morsecode
*/
public String convertMorsecodeToBuchstabe(String input) {
StringBuilder sb = new StringBuilder();
String buchstabe;
String[] morsecodes = input.split(" ");
// Durch alle char im übergebenen String loopen
for(String morsecode : morsecodes) {
// Wenn der char in der codeMap enthalten ist, an den Rückgabe String anheften, ansonsten nichts ignorieren.
buchstabe = this.getBuchstabe(morsecode);
if(buchstabe != null) {
sb.append(buchstabe).append(' ');
}
}
// Gibt den konvertierten String zurück
return sb.toString();
}
}
package enigma.model;
/**
* Klasse Reflektor
* <p>
* Der Reflektor nimmt einen Buchstaben der Klasse Walze entgegen und und kodiert diesen.
* Der kodierte Buchstabe wird an die Klasse Walze wieder zurückgegeben.
* <p>
* Prinzipiell verhält sich die Klasse Refelktor wie die Klasse Walze, außer das sie sich
* nach Betätigung einer Taste nicht dreht (starr montiert) und sie gibt keine Signale
* an andere Walzen zum drehen.
*/
public class Reflektor {
/**
* Konstanten und Variablen der Klasse Reflektor
* <p>
* WALZE_ALPHABET : konstanter Char-Array mit den Werten des Alphabeths (26 Werte)
* WALZE_REFLEKTOR : konstanter Char-Array mit den Werten des Reflektors (26 Werte)
* reflektorBuchstabeRein : Character mit dem an die Klasse übergebenen Character
* reflektorBuchstabeRaus : Character nach der Codierung in der Klasse Reflektor
* iPositionReflektor : Integer mit der Positionsnummer des Characters im Array
*/
private final Character[] WALZE_ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
private final Character[] WALZE_REFLEKTOR = {'E', 'J', 'M', 'Z', 'A', 'L', 'Y', 'X', 'V', 'B', 'W', 'F', 'C', 'R', 'Q', 'U', 'O', 'N', 'T', 'S', 'P', 'I', 'K', 'H', 'G', 'D'};
/**
* Funktion Codiere
* <p>
* Durchsucht das konstante Char-Array WALZE_ALPHABET nach der Position eines bestimmten
* Buchstabens und gibt den Character an der entsprechenden Position im konstanten
* Char-Array WALZE_REFLEKTOR zurück.
*
* @return reflektorBuchstabeRaus: Character: Der kodierte Buchstabe aus dem Reflektor
*/
public char codiere(Character buchstabe) {
int iPositionReflektor = 0;
/*Ermittelt die Position des Buchstaben buchstabe auf der Alphabetswalze*/
for (int index = 0; index < WALZE_ALPHABET.length; index++) {
if (buchstabe.equals(WALZE_ALPHABET[index])) {
iPositionReflektor = index;
break;
}
}
/*Im Char-Array WALZE_REFLEKTOR wird der Character an der Position iPositionReflektor ausgegeben*/
return WALZE_REFLEKTOR[iPositionReflektor];
}
}
package enigma.model;
/**
*TODO Dokumentieren
*/
public class Steckbrett {
/**
*TODO Dokumentieren
*/
private int zaehler;
private Character[] orginalBuchstaben;
private Character[] getauschteBuchstaben;
/**
*TODO Dokumentieren
*/
public Steckbrett() {
orginalBuchstaben = new Character[10];
getauschteBuchstaben = new Character[10];
}
/**
*TODO Dokumentieren
*
* @param buchstabe1 : char
* @param buchstabe2 : char
* @return boolean
*/
public boolean setzeVertauschung(char buchstabe1, char buchstabe2) {
if (zaehler < orginalBuchstaben.length) {
orginalBuchstaben[zaehler] = buchstabe1;
getauschteBuchstaben[zaehler++] = buchstabe2;
} else {
System.err.println("Zu viele Vertauschungen angegeben!");
}
return ueberpruefeVertauschungen();
}
/**
*TODO Dokumentieren
*
* @return boolean
*/
public boolean ueberpruefeVertauschungen() {
boolean result = true;
for (int n = 0; n < orginalBuchstaben.length; n++) {
if (orginalBuchstaben.equals(orginalBuchstaben[n]) || getauschteBuchstaben.equals(orginalBuchstaben[n]) || getauschteBuchstaben.equals(getauschteBuchstaben[n])) {
System.err.println("Vertauschungen enthalten unzulässige Dopplungen");
result = false;
}
}
return result;
}
/**
* TODO Dokumentieren
*
* @param buchstabe : Character
* @return char
*/
public char codiere(Character buchstabe) {
for (int index = 0; index < getauschteBuchstaben.length; index++) {
if (buchstabe.equals(getauschteBuchstaben[index])) {
buchstabe = orginalBuchstaben[index];
} else if (buchstabe.equals(orginalBuchstaben[index])) {
buchstabe = getauschteBuchstaben[index];
}
}
return buchstabe;
}
}
package enigma.model;
/**
* Klasse Walze
* <p>
* Erzeugt ein Objekt des Typs Walze mit den Eigenschaften:
* <p>
* 1. Walzennummer (Die Walze enthält die 26 Buchstaben des Alphabeths und codiert diese.
* 5 verschiedene Walzen stehen zur Auswahl, die jeweils verschieden die Buchstaben des Alphabeths
* paarweise vertauschen)
* <p>
* 2. Ringstellung (Umspringpunkt der Walze wird festgelegt. Der Umspringpunkt bestimmt
* den Drehzeitpunkt der linken Nachbarwalze)
*/
public class Walze {
/**
* Konstanten und Variablen der Klasse Walze
* <p>
* buchstabe : Bestimmt den Buchstaben
* ringstellung : Bestimmt den Umspringpunkt der Walze
* walzennr : Bestimmt die Walzennr. (also wie der Buchstabe codiert wird)
* iPositionBuchstabe : gibt die Position des Buchstabens auf dem Array der Walze wieder.
* iPositionBuchstabeRe : gibt die Position des codierten Buchstabens im Alphabet wieder.
* private Character[] walze : Character-Array der Walze
*/
/*Alphawalze*/
private Character[] walzeAlpha;
private Character buchstabe;
private char ringstellung;
private int walzennr;
private Character[] alphabet;
/**
* Gibt die Parameter der Walze mit
*
* @param walzennr : int : Nummer der gewaehlten Walze
* @param ringstellung : Character : Einstellung des Notch
*/
public Walze(int walzennr, int ringstellung) {
this.alphabet = new Character[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
this.walzennr = walzennr;
this.buchstabe = 'A';
this.ringstellung = this.alphabet[ringstellung - 1];
this.walzeAlpha = new Character[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
}
/**
* Sortiert den Walzennummern das passenden Character-Array mittels switch zu.
*
* @return walze : Character[] : gibt die gewaehlte Walze zurueck
*/
private Character[] walzenNummer() {
Character[] walze = new Character[26];
Character[] walzeEins = {'E', 'K', 'M', 'F', 'L', 'G', 'D', 'Q', 'V', 'Z', 'N', 'T', 'O', 'W', 'Y', 'H', 'X', 'U', 'S', 'P', 'A', 'I', 'B', 'R', 'C', 'J'};
Character[] walzeZwei = {'A', 'J', 'D', 'K', 'S', 'I', 'R', 'U', 'X', 'B', 'L', 'H', 'W', 'T', 'M', 'C', 'Q', 'G', 'Z', 'N', 'P', 'Y', 'F', 'V', 'O', 'E'};
Character[] walzeDrei = {'B', 'D', 'F', 'H', 'J', 'L', 'C', 'P', 'R', 'T', 'X', 'V', 'Z', 'N', 'Y', 'E', 'I', 'W', 'G', 'A', 'K', 'M', 'U', 'S', 'Q', 'O'};
Character[] walzeVier = {'E', 'S', 'O', 'V', 'P', 'Z', 'J', 'A', 'Y', 'Q', 'U', 'I', 'R', 'H', 'X', 'L', 'N', 'F', 'T', 'G', 'K', 'D', 'C', 'M', 'W', 'B'};
Character[] walzeFuenf = {'V', 'Z', 'B', 'R', 'G', 'I', 'T', 'Y', 'U', 'P', 'S', 'D', 'N', 'H', 'L', 'X', 'A', 'W', 'M', 'J', 'Q', 'O', 'F', 'E', 'C', 'K'};
switch (this.walzennr) {
case 1:
walze = walzeEins;
break;
case 2:
walze = walzeZwei;
break;
case 3:
walze = walzeDrei;
break;
case 4:
walze = walzeVier;
break;
case 5:
walze = walzeFuenf;
break;
}
return walze;
}
/**
* TODO Dokumentieren
*
* @return ringstellung : Character : gibt die neue Ringstellung zurueck
*/
public char getRingstellung() {
return ringstellung;
}
/**
* Gibt die Initiale Ringstellung der Walze an.
* Es sind nur Zahlen von 1 - 26 zugelassen.
* Im Fehlerfall wird die Ringstellung standardmaessig auf '1' gesetzt.
*
* @param ringstellung : Character : Punkt an dem die Walze umspringt
*/
public void setRingstellung(int ringstellung) {
if (ringstellung > 0 && ringstellung <= 26) {
this.ringstellung = this.alphabet[ringstellung - 1];
} else {
this.ringstellung = 'Z';
}
}
/**
* dreheWalze() return boolean => Wenn Notch erreicht, gib true zurück, ansonsten false
* TODO Doku
*/
public boolean dreheWalze(int... drehung) {
boolean checkRing = false;
verschiebung();
if (drehung.length > 0) {
for (int i = 1; i < drehung[0]; i++) {
verschiebung();
}
}
if (this.getPosition().equals(this.ringstellung)) {
checkRing = true;
}
return checkRing;
}
/**
* TODO Dokumentieren
*/
private void verschiebung() {
Character[] neueWalze = new Character[26];
for (int index = 0; index < neueWalze.length; index++) {
neueWalze[(index + 1) % neueWalze.length] = this.walzeAlpha[index];
}
this.walzeAlpha = neueWalze;
}
public char getAnzeige() {
int temp = this.getArrayIndex('A', this.walzeAlpha);
return this.alphabet[temp];
}
/**
* Chiffriert den Buchstaben an der Position aus der Methode positionBuchstabe()
* anhand der gewaehlten Walze.
*
* @return chiffrierterBuchstabe : Character : chiffrierter Buchstabe
*/
public char codiere(char buchstabe) {
for (int i = 0; i < walzeAlpha.length; i++) {
if (walzeAlpha[i].equals(buchstabe)) {
buchstabe = walzenNummer()[i];
break;
}
}
return buchstabe;
}
/**
* Chiffriert den Buchstaben an der Position aus der Methode positionBuchstabeReverse()
* anhand der AlphaWalze.
*
* @return codierterBuchstabeRe : Character : chiffrierter Buchstabe
*/
public char codiere2(char buchstabe) {
for (int i = 0; i < walzenNummer().length; i++) {
if (walzenNummer()[i].equals(buchstabe)) {
buchstabe = walzeAlpha[i];
break;
}
}
return buchstabe;
}
/**
* TODO Dokumentieren
*
* @return buchstabe : Character : gibt den neuen Buchstaben zurueck
*/
public Character getBuchstabe() {
return buchstabe;
}
/**
* TODO Dokumentieren
*
* @param buchstabe : Character
* @param array : Character[]
* @return int
*/
private int getArrayIndex(Character buchstabe, Character[] array) {
int result = -1;
for (int i = 0; i < array.length; i++) {
if (array[i].equals(buchstabe)) {
result = i;
break;
}
}
return result;
}
/**
* Definiert die Walze. Es stehen fuenf Walze zur Auswahl.
*
* @param walzennr : int : setzt die Walzennummer
*/
public void setWalzennr(int walzennr) {
if (walzennr > 0 && walzennr < 6) {
this.walzennr = walzennr;
} else {
System.err.println("Keine gültige Walzennummer");
}
}
/**
* TODO: Dokumentieren
*
* @return Character
*/
public Character getPosition() {
return walzeAlpha[0];
}
/**
* Gibt die Grundeinstellung der Walze ein. Nur Buchstaben von A - Z sind zugelassen.
* Buchstaben werden automatisch in Grossbuchstaben umgewandelt.
* Im Fehlerfall wird die Grundeinstellung der Walze standardmaessig auf 'A' gesetzt.
* TODO Funktionsname hat sich geändert
*
* @param buchstabe : Character : Grundeinstellung der Walze
*/
public void setPosition(Character buchstabe) {
if (Character.isLetter(buchstabe)) {
this.buchstabe = Character.toUpperCase(buchstabe);
System.arraycopy(this.alphabet, 0, this.walzeAlpha, 0, this.alphabet.length);
if (buchstabe > 'A') {
dreheWalze(this.getArrayIndex(buchstabe, this.alphabet));
}
} else {
this.buchstabe = 'A';
}
}
}
package projekt.enigma;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import projekt.enigma.model.Fehler;
import java.io.IOException;
/**
* JavaFX App
* Startklasse fuer JavaFX Application, durch die Erweiterung um die Klasse Application.
* Baut die Benutzeroberflaeche in ihren Grundstrukturen auf.
*/
public class App extends Application {
/**
* Deklariert den GuiController.
*/
private static GuiController gc;
/**
* debug : int : fuer die Funktion debug der Klasse Fehler notwendig.
*/
private static int debug;
/**
* Startet die Klasse App und setzt den debug-Wert 1.
*
* @param args : String[] : Standard-Kommandozeilen-Argument.
*/
public static void main(String[] args) {
debug = 0;
launch(args);
}
/**
* Gibt der Getter einen int > 0 zurueck, wird eine Meldung auf der Konsole ausgegeben.
*
* @return debug : int : bestimmt die Eingabe der debung-Methode in der Klasse Fehler.
*/
public static int getDebug() {
return debug;
}
/**
* Initialisierung der Variablen fuer die JavaFX Scene Kenngruppe.
* Abfrage der Kenngruppe und Reaktion auf die Eingabe.
*
* @param primaryStage : Stage : Fenster zur Eingabe der Kenngruppe.
* @throws IOException : wird bei fehlerhafter Eingabe geworfen.
*/
@Override
public void start(Stage primaryStage) throws IOException {
primaryStage.setTitle("Enigma");
primaryStage.setResizable(false);
Label lblEingbae = new Label("Bitte Kenngruppe eingeben!");
TextField tfEingabe = new TextField();
Button btnKenngruppe = new Button("Kenngruppe setzen!");
VBox layout = new VBox();
layout.setSpacing(10);
layout.setPadding(new Insets(20, 30, 10, 30));
btnKenngruppe.setMaxWidth(Double.MAX_VALUE);
// baut die Scene fuer die Kenngruppenabfrage auf
layout.getChildren().addAll(lblEingbae, tfEingabe, btnKenngruppe);
Scene sceKenngruppe = new Scene(layout);
// laden der FXML und der Enigma-Ansicht, um Ladezeiten zu verringern
FXMLLoader guiLoader = new FXMLLoader(App.class.getResource("gui.fxml"));
Scene sceApp = new Scene(guiLoader.load(), 962, 677);
/*Bestaetigen der Kenngruppe, Ausgabe einer Fehlermeldung im Fall einer falschen Eingabe und starten
des Enigma-Fensters */
tfEingabe.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
if (enter(tfEingabe.getText())) {
gc = guiLoader.getController();
gc.setKenngruppe(tfEingabe.getText());
primaryStage.setScene(sceApp);
} else {
tfEingabe.setText("");
new Fehler().showErrorDialog("error", "Kenngruppe falsch",
"Regeln für die Kenngruppe: 4-8 Zeichen sowie nur Buchstaben von A-Z.");
}
}
});
btnKenngruppe.setOnAction(e -> {
if (enter(tfEingabe.getText())) {
gc = guiLoader.getController();
gc.setKenngruppe(tfEingabe.getText());
primaryStage.setScene(sceApp);
} else {
tfEingabe.setText("");
new Fehler().showErrorDialog("error", "Kenngruppe falsch",
"Regeln für die Kenngruppe: 4-8 Zeichen sowie Buchstaben von A-Z.");
}
});
primaryStage.setScene(sceKenngruppe);
primaryStage.show();
}
/**
* Ueberprueft die Gueltigkeit der Kenngruppeneingabe.
* Nur Zeichen von A-Z sind zugelassen und die Kenngruppe muss aus mind. 4 und max. 8 Zeichen bestehen.
*
* @param kenngruppe : String : Eingabewert aus dem Fenster.
* @return result : boolean : ist die Kenngruppe ungueltig wird false zurueckgegeben, sonst true.
*/
private boolean enter(String kenngruppe) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
boolean result = true;
for (char c : kenngruppe.toUpperCase().toCharArray()) {
if (!alphabet.contains(String.valueOf(c))) {
result = false;
break;
}
}
if ((kenngruppe.length() > 8) || (kenngruppe.length() < 4)) {
result = false;
}
return result;
}
}
This diff is collapsed.
package projekt.enigma;
/**
* Startpunkt des Programms. Startet die Klasse App und damit die GUI.
*/
public class Main {
/**
* Startet die App
*
* @param args : String[] : Standard-Kommandozeilen-Parameter.
*/
public static void main(String[] args) {
App.main(args);
}
}
package projekt.enigma.database;
import java.sql.*;
/**
* Dies ist die SQLite Datenbank Klasse.
* In der SQLite Datei im Resources Ordner liegt das Codebuch welches benoetigt wird um die
* Nachrichten mit der Enigma zu ver/entschluesseln.
* Die Datenbank ist statisch und deshalb konnte sie im Resources Ordner hinterlegt werden.
* Für jeden Tag des Monats (1-31) ist ein eigener Eintrag enthalten welcher ueber die Funktion
* getCodebuch abgerufen werden kann.
* Zurueckgegeben wird ein Array welcher in der getCodebuch Funktion genauer dokumentiert ist.
*/
public class DatenbankSqlite {
/**
* Verbindung zur SQLite Datenbank aufbauen.
* Die Datei liegt in den Resources und aendert sich nicht,
* weshalb der Pfad zu derselben fest hinterlegt ist.
*
* @return conn : Connection: statische Datenbankverbindung.
*/
private Connection connect() {
String url = "jdbc:sqlite::resource:projekt/enigma/codebuch.sqlite";
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* Liest das Codebuch aus der SQLite Datenbank aus.
* Dieser Funktion muss ein tag als int Wert uebergeben werden.
* Anschließend wird eine Verbindung zur SQLite Datenbank aufgebaut und das Codebuch angefragt.
* Dieses wird in ein Objekt vom Typ Codebuch gepackt und zurueckgegeben.
*
* Holt den heutigen Eintrag aus der SQLite Datenbank und erstellt daraus ein Codebuch Objekt.
*
* @param tag : int : Tag fuer welchen ein Codebuch benoetigt wird.
* @return String : Die Einstellungen des angefragten Tages.
* <p>
* String[0] : Tag
* String[1] : Walzenlage
* String[2] : Ringstellung
* String[3] : Steckverbindung
* </p>
*/
public String[] getCodebuch(int tag) {
String[] codebuch = new String[4];
try {
Connection conn = this.connect();
PreparedStatement pstm = conn.prepareStatement("SELECT * FROM table_codebuch WHERE Tag = ? LIMIT 1");
pstm.setInt(1, tag);
ResultSet rs = pstm.executeQuery();
while (rs.next()) {
codebuch[0] = rs.getString("Tag");
codebuch[1] = rs.getString("Walzenlage");
codebuch[2] = rs.getString("Ringstellung");
codebuch[3] = rs.getString("Steckverbindung");
}
} catch (SQLException ignored) {}
return codebuch;
}
}
package enigma.model;
package projekt.enigma.model;
import projekt.enigma.database.DatenbankSqlite;
import java.time.LocalDate;
import java.time.ZoneId;
/**
* Das Codebuch war eines der essentiel wichtigen Sachen bei der Enigma.
* Jeder Enigma gehörte auch ein Codebuch bei, welches notwenidg war um die Nachrichten zu ver/entschlüsseln.
* Das Codebuch war eines der essentiell wichtigen Sachen bei der Enigma.
* Jeder Enigma gehoerte auch ein Codebuch bei, welches notwendig war um die Nachrichten zu ver/entschluesseln.
* Im Codebuch standen für jeden Tag des Monats die notwendigen Einstellungen welche vorgenommen werden
* mussten um die Texte zu ver/entschlüsseln.
* Hiernach wurden die Walzen eingesetzt, die Ringe für den Rücksprung der Walze gesetzt und deren Grundeinstellung
* mussten, um die Texte zu ver/entschluesseln.
* Hiernach wurden die Walzen eingesetzt, die Ringe für den Ruecksprung der Walze gesetzt und deren Grundeinstellung
* vorgenommen.
* Bei der Enigma um welche es hier geht (Enigma I) gab es zusätzlich ein Steckbrett, welches ebenfalls im Codebuch
* Bei der Enigma I, um welche es hier geht, gab es zusaetzlich ein Steckbrett, welches ebenfalls im Codebuch
* festgelegt war.
* <p>
* Dieses Codebuch Objekt enthält die Einstellungen eines Tages, welche mittels Getter und Setter
* verarbeitet werden können.
* Dieses Codebuch enthaelt die Einstellungen eines Tages, welche mittels Getter und Setter
* verarbeitet werden koennen.
* <p>
* Zusätzlich gibt es zu Debug Zwecken eine überschriebene toString Funktion welche das Objekt als String zurück
* geben kann.
* Zusaetzlich gibt es zu Debug-Zwecken eine ueberschriebene toString Funktion, welche das Objekt als String
* zurueckgeben kann.
*/
public class Codebuch {
//region Variablen
/**
* TODO Dokumentieren
* tag : int : gibt den Tag eines Monats an.
*/
private int tag;
/**
* walzenlage : int[] : legt die Positionen der drei Walzen fest.
*/
private int[] walzenlage;
/**
* ringstellung : int[] : legt die Ringstellungen der drei Walzen fest.
*/
private int[] ringstellung;
/**
* steckverbindung : char[][] : legt die Steckverbindungen im Steckbrett fest.
*/
private char[][] steckverbindung;
//endregion
//region Konstruktor
/**
* Im Konstruktor werden die Standart Werte gesetzt
* Im Konstruktor werden die Standardwerte gesetzt.
* <p>
* walzenlage : int[3] : Hier wird die Position der drei Walzen festgelegt.
* ringstellung : char[3] : Jede Walze hat einen Ring. Der Index steht für die Walze und der Value für
* die Position des Ringes.
* steckverbindung : char[10][] : Zehn Kabel können in das Steckbrett gesteckt werden. In diesem Array werden
* die Kabel mit ihren jeweiligen Buchsen hinterlegt.
* ringstellung : char[3] : Jede Walze hat einen Ring. Der Index steht fuer die Walze und der Value fuer
* die Position des Ringes.
* steckverbindung : char[10][] : Zehn Kabel koennen in das Steckbrett gesteckt werden. In diesem Array werden
* die Kabel mit ihren jeweiligen Buchsen hinterlegt.
*/
public Codebuch() {
this.walzenlage = new int[3];
......@@ -46,48 +68,80 @@ public class Codebuch {
}
}
//endregion
//region Funktionen & Methoden
/**
* Holt den Tagesschluessel aus dem Codebuch ab. Ist kein Tag angegeben, wird der aktuelle Tag genutzt.
* Aus dem Tagesschluessel werden die Werte fuer die Walzenlage, Ringstellung und Steckverbindung
* gesetzt.
*
* @param tag : int[] : gibt keinen, einen Tag oder mehrere Tage mit.
*/
public void fetchTagesschluessel(int... tag) {
String[] walzenlage, ringstellung, db;
if (tag.length > 0) {
db = new DatenbankSqlite().getCodebuch(tag[0]);
} else {
db = new DatenbankSqlite().getCodebuch(LocalDate.now(ZoneId.of("Europe/Berlin")).getDayOfMonth());
}
this.setTag(Integer.parseInt(db[0]));
// setzen der Walzenlage, Ringstellung, Steckverbindung
walzenlage = db[1].split(",");
for (int i = 0; i < 3; i++) {
this.setWalzenlage(i, Integer.parseInt(walzenlage[i]));
}
ringstellung = db[2].split(",");
for (int i = 0; i < 3; i++) {
this.setRingstellung(i, Integer.parseInt(ringstellung[i]));
}
this.setSteckverbindung(db[3].split(","));
}
/**
* Gibt die aktuelle Instanz des Codebuches als String zurück.
* Hierbei werden der Tag die Walzenlagen, Ring/Grundstellung sowie die Steckverbindungen zurück gegeben.
* Gibt die aktuelle Instanz des Codebuches als String zurueck.
* Hierbei werden der Tag die Walzenlagen, Ring-/Grundstellung sowie die Steckverbindungen zurueckgegeben.
*
* @return String : String des gesamten Objektes
* @return String : String des gesamten Objektes.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
boolean wlLoop = false;
boolean rsLoop = false;
boolean svLoop = false;
// Tag des aktuellen Codebuch Eintrags
sb.append("Tag: ").append(this.getTag()).append("\n");
// In welchem Slot steckt die Walze?
sb.append("Walzenlage: ");
for (int wl : this.getWalzenlage()) {
sb.append(wl).append(",");
wlLoop = true;
}
// TODO
if (this.getWalzenlage().length > 0) {
sb.setLength(sb.length() - 1);
}
sb.append("\n");
// Die Ringstellung an den Walzen
sb.append("Ringstellung: ");
for (int rs : this.getRingstellung()) {
sb.append(rs).append(",");
rsLoop = true;
}
if (rsLoop) {
if (this.getRingstellung().length > 0) {
sb.setLength(sb.length() - 1);
}
sb.append("\n");
// Das Steckbrett und wie die Kabel angeschlossen sind
sb.append("Steckverbindung: ");
for (char[] verbindung : this.getSteckverbindung()) {
sb.append(verbindung[0]).append(":").append(verbindung[1]).append(",");
svLoop = true;
}
if (svLoop) {
if (this.getSteckverbindung().length > 0) {
sb.setLength(sb.length() - 1);
}
sb.append("\n");
......@@ -95,88 +149,93 @@ public class Codebuch {
return sb.toString();
}
//endregion
//region Setter
/**
* Gibt den Tag dieser Instanz zurück
* Setzt die Steckverbindung dieser Instanz.
*
* @return int : Tag
* @param kabel : String[] : Die Steckverbindungen die gesteckt werden sollen.
* Jeder Eintrag im Array ist ein String mit zwei Zeichen.
* Diese werden in zwei chars zerlegt und anschließend im globalen Array gespeichert.
*/
public int getTag() {
return tag;
private void setSteckverbindung(String[] kabel) {
int counter = 0;
for (String stecker : kabel) {
char[] verbindung = new char[2];
verbindung[0] = stecker.charAt(0);
verbindung[1] = stecker.charAt(1);
this.steckverbindung[counter++] = verbindung;
}
}
/**
* Setzt den Tag dieser Instanz
* Setzt die Walzenlage dieser Instanz.
*
* @param tag : int
* @param position : int : Position der Walze.
* @param walzenlage : int : Welche Walze wurde eingesetzt.
*/
public void setTag(int tag) {
this.tag = tag;
private void setWalzenlage(int position, int walzenlage) {
this.walzenlage[position] = walzenlage;
}
/**
* Gibt die Walzenlage dieser Instanz zurück
* Setzt die Ringstellung dieser Instanz.
*
* @return String[] : Walzenlage
* @param position : int : Auf welche Walze wird der Ring aufgesetzt?
* @param ringstellung : int : An dieser Position soll die nächste Walze weiter gedreht werden.
*/
public int[] getWalzenlage() {
return walzenlage;
private void setRingstellung(int position, int ringstellung) {
this.ringstellung[position] = ringstellung;
}
/**
* Gibt die Ringstellung dieser Instanz zurück
* Setzt den Tag dieser Instanz.
*
* @return String[] : Ringstellung
* @param tag : int : Tag.
*/
public int[] getRingstellung() {
return ringstellung;
void setTag(int tag) {
this.tag = tag;
}
//endregion
//region Getter
/**
* Gibt die Steckverbindung dieser Instanz zurück
* Gibt den Tag dieser Instanz zurueck.
*
* @return String[] : Steckverbindung
* @return int : Tag.
*/
// TODO
public char[][] getSteckverbindung() {
return this.steckverbindung;
public int getTag() {
return tag;
}
/**
* Setzt die Steckverbindung dieser Instanz
* Gibt die Walzenlage dieser Instanz zurueck.
*
* @param kabel : String[] : Die Steckverbindungen die gesteckt werden sollen.
* Jeder Eintrag im Array ist ein String mit zwei Zeichen.
* Diese werden in zwei char zerlegt und anschließend im globalen
* Array gespeichert.
* @return walzenlage : int[] : Walzenlage.
*/
public void setSteckverbindung(String[] kabel) {
int counter = 0;
for (String stecker : kabel) {
char[] verbindung = new char[2];
verbindung[0] = stecker.charAt(0);
verbindung[1] = stecker.charAt(1);
this.steckverbindung[counter++] = verbindung;
}
public int[] getWalzenlage() {
return walzenlage;
}
/**
* Setzt die Walzenlage dieser Instanz
* Gibt die Ringstellung dieser Instanz zurueck.
*
* @param position : int : Position der Walze
* @param walzenlage : int : Welche Walze wurde eingesetzt
* @return ringstellung : int : Ringstellung.
*/
public void setWalzenlage(int position, int walzenlage) {
this.walzenlage[position] = walzenlage;
public int[] getRingstellung() {
return ringstellung;
}
/**
* Setzt die Ringstellung dieser Instanz
* Gibt die Steckverbindungen dieser Instanz zurueck.
*
* @param position : int : Auf welche Walze wird der Ring aufgesetzt?
* @param ringstellung : char : An dieser Position soll die nächste Walze weiter gedreht werden.
* @return steckerverbindung : char[][] : Steckverbindung.
*/
public void setRingstellung(int position, int ringstellung) {
this.ringstellung[position] = ringstellung;
public char[][] getSteckverbindung() {
return this.steckverbindung;
}
//endregion
}
package projekt.enigma.model;
import java.io.IOException;
import java.util.Calendar;
import java.util.Random;
/**
* Die Codierer-Klasse beschreibt den Benutzer, welcher die Enigma benutzt.
* Alle Vorgaenge, wie z.B. das zusammenbauen der Hardware, auslesen des Codebuches und das anschließende codieren,
* finden hier statt. Dieser ist quasi die Schnittstelle zwischen der GUI (Hauptmann, welcher ihm sagt was er zu
* verschluesseln hat), der Enigma und dem Funker im Funkraum, welcher die Nachricht im Anschluss versendet.
*/
public class Codierer {
//region Variablen
/**
* Der Spruchschluessel als Klartext zur Codierung der Nachricht.
*/
private String spruchschluessel;
/**
* Der Spruchschluessel, mit den Tageswerten aus dem Codebuch, codiert.
*/
private String spruchschluesselCodiert;
/**
* Die Kenngruppe fuer die die versendeten Nachrichten gedacht sind.
* Diese ist relevant fuer den Webservice (Funkraum).
*/
private String kenngruppe;
/**
* Die Nachricht, welche der Benutzer eingibt, wird als String "nachricht" gespeichert
* und im Laufe der Benutzung ergaenzt.
*/
private String nachricht;
/**
* Das Hardware-Objekt. Hier werden alle hardwarerelevanten Baugruppen gespeichert und verarbeitet.
*/
private Hardware hardware;
/**
* Im Codebuch sind die Tageswerte zu finden. Ueber dieses Objekt kann darauf zugegriffen werden.
*/
private Codebuch codebuch;
//endregion
//region Konstruktor
/**
* Der Konstruktor des Codierers.
* Hier werden die globalen Variablen auf ihre Standardwerte gesetzt sowie die Objekte initialisiert.
*/
public Codierer(String kenngruppe) {
this.nachricht = "";
this.spruchschluessel = "";
this.spruchschluesselCodiert = "";
this.kenngruppe = kenngruppe;
this.codebuch = new Codebuch();
this.codebuch.fetchTagesschluessel();
}
//endregion
//region Funktionen & Methoden
//region Reset & Initialisieren
/**
* 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.
* <br>
* Ein Reflektor wird definiert, jedoch keine Werte zugewiesen, da wir nur einen besitzen und
* deshalb alle Einstellungen hierfuer statisch im Reflektor definiert haben.
* <br>
* Das Steckbrett wird ebenfalls definiert und die notwendigen Kabel eingesteckt nach dem heutigen
* Codebucheintrag.
*/
private void initialisiereHardware() {
this.nachricht = "";
// Das Steckbrett initialisieren
Steckbrett sb = new Steckbrett();
char[][] verbinder = this.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
this.hardware.setWalzen(0, this.codebuch.getWalzenlage()[0], this.codebuch.getRingstellung()[0]);
this.hardware.setWalzen(1, this.codebuch.getWalzenlage()[1], this.codebuch.getRingstellung()[1]);
this.hardware.setWalzen(2, this.codebuch.getWalzenlage()[2], this.codebuch.getRingstellung()[2]);
// Der Hardware das gesetzte Steckbrett zuweisen
this.hardware.setSteckbrett(sb);
// Ein Reflektor-Objekt erstellen und der Hardware bekanntgeben
this.hardware.setReflektor(new Reflektor());
}
/**
* Setzt die Enigma auf die Einstellungen des aktuellen Tages, aus dem Codebuch zurueck.
*/
public void resetHardware() {
this.initialisiereHardware();
}
/**
* Leert das Nachrichten-Objekt um eine neue Nachricht aufnehmen zu koennen.
*/
private void resetNachricht() {
this.nachricht = "";
}
//endregion
//region Nachrichten handler
/**
* Befehl, die Nachricht an den Funker zu uebergeben.
*
* @throws IOException : Die Antwort konnte nicht gelesen werden.
*/
public void sendeNachricht() throws IOException {
String kopf = this.generateKopf();
new Funkraum().sendeFunkspruch(new Morsecode().convertBuchstabeToMorsecode(kopf + this.nachricht),
this.kenngruppe);
this.nachricht = "";
this.resetHardware();
}
/**
* Gibt die letzte empfangene Nachricht zurueck.
* <br>
* nachricht[0]: String[]: Tag, an dem die Nachricht gesendet wurde.
* nachricht[1]: String[]: Die verschluesselte Nachricht von Morsecode in Buchstaben konvertiert.
* nachricht[2]: String[]: Nachricht im Klartext. Die Enigma Nachricht (nachricht[1]) mittels der
* Tageseinstellungen (nachricht[0]) decodiert.
*/
public String[] empfangeNachricht() {
StringBuilder sb = new StringBuilder();
Morsecode mc = new Morsecode();
String[] nachricht = new String[3];
// Alte Nachrichten-Variable erstmal leeren
this.nachricht = "";
// Abrufen der letzten Nachricht, für unsere Kenngruppe, aus dem Funkraum
String[] codierteNachricht = new Funkraum().empfangeFunkspruch(this.kenngruppe);
// Prüfen ob Nachrichtenlänge > 1 und die codierte Nachricht mehr als drei Felder (" ") hat
if ((codierteNachricht[1] != null) && (codierteNachricht[1].split(" ").length > 3)) {
nachricht[0] = codierteNachricht[0];
nachricht[1] = mc.convertMorsecodeToBuchstabe(codierteNachricht[1]);
nachricht[2] = this.decodiere(nachricht[1], Integer.parseInt(nachricht[0]));
sb.append(nachricht[1], 0, 16);
for (int i = 17; i <= nachricht[1].length(); ) {
if ((i + 5) < nachricht[1].length()) {
sb.append(nachricht[1], i, i + 5).append(" ");
i += 5;
} else {
sb.append(nachricht[1].substring(i));
break;
}
}
nachricht[1] = sb.toString();
}
return nachricht;
}
//endregion
//region Generatoren
/**
* Hier wird ein neuer Spruchschluessel generiert.
* <p>
* Mit diesem werden die Walzen auf eine neue Startposition gestellt und dem Kopf, mit dem
* Tagesschluessel codiert, hinzugefuegt.
* <br>
* Hierfuer wird mittels der Funktion "randomBuchstabe" ein zufaelliger Buchstabe generiert,
* und ueberprueft, ob dieser bereits in der globalen Variable (this.spruchschluessel) vorhanden ist.
* Wenn nicht, wird der Buchstabe dem Spruchschluessel hinzugefügt.
* <br>
* Dies wir nun so lange gemacht bis der Spruchschluessel eine Laenge von drei Zeichen hat.
* Die Walzen werden anhand des Spruchschluessels automatisch gestellt.
*/
public void generateSpruchschluessel() {
String klartext = "";
while (klartext.length() < 3) {
String temp = this.randomBuchstabe();
if (!klartext.contains(temp)) {
klartext += temp;
}
}
this.spruchschluessel = klartext;
this.spruchschluesselCodiert = this.codiere(klartext + klartext, false);
// Walzen auf den Spruchschlüssel stellen
this.hardware.setzePosition(0, this.spruchschluessel.charAt(0));
this.hardware.setzePosition(1, this.spruchschluessel.charAt(1));
this.hardware.setzePosition(2, this.spruchschluessel.charAt(2));
// Die Kenngruppe codieren und in der Nachricht speichern
this.codiere(this.kenngruppe, true);
}
/**
* Erstellen des Nachrichten-Kopfes.
* Hierfuer wird die aktuelle Uhrzeit ausgelesen, die Laenge der Nachricht, sowie der, mit dem
* Tagescode codierte, Spruchschluessel.
*
* @return String: Enthaelt die Uhrzeit, die Anzahl der Buchstaben der Nachricht und den Spruchschluessel.
*/
private String generateKopf() {
Calendar cal = Calendar.getInstance();
return String.format("%02d%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)) + " "
+ this.nachricht.length() + " " + this.spruchschluesselCodiert.substring(0, 3) + " "
+ this.spruchschluesselCodiert.substring(3, 6) + " ";
}
/**
* Generiert einen zufaelligen Buchstaben aus dem Alphabet.
* In der Funktion gibt es den String "Alphabet", in welchem alle zulaessigen Zeichen eingetragen sind.
* Aus diesem String wird nun zufaellig ein Zeichen ausgewaehlt und zurueckgegeben.
*
* @return String : ein zufaellig generierter Buchstabe.
*/
private String randomBuchstabe() {
return String.valueOf((char) ('A' + new Random().nextInt(26)));
}
//endregion
//region setze Funktionen
/**
* Setzt den Ring auf der Walze auf einen neuen Umsprungwert.
*
* @param walzenPosition : int : Walze auf die der Ring gesteckt wird.
* @param umsprungPunkt : int : Umspringpunkt (Signal an linke Walze zum Drehen).
*/
public void setzeRing(int walzenPosition, int umsprungPunkt) {
this.hardware.setzeRing(walzenPosition, umsprungPunkt);
}
/**
* Setzt die Walze (walzeNr) in die Position (walzenPosition) der Enigma ein.
* Mit Ringstellung(ringstellung) gibt man die Position des Umsprungpunktes an.
*
* @param walzenPosition : int : Position der Walze in der Enigma (1-2-3).
* @param walzeNr : int : Nummer der Walze die eingesetzt wird.
* @param ringstellung : int : Stellung des Ringes.
*/
public void setzeWalzeNr(int walzenPosition, int walzeNr, int ringstellung) {
this.hardware.setzeWalzenNr(walzenPosition, walzeNr, ringstellung);
}
/**
* Setzt den anzuzeigenden Buchstaben (buchstabe) auf der Walze (walzenPosition) und resetet das
* Nachrichten Objekt
*
* @param walze : int : Nummer der Walze
* @param buchstabe : char : Buchstabe der zugewiesen soll
*/
public void setzeWalzenPosition(int walze, char buchstabe) {
this.resetNachricht();
this.hardware.setzePosition(walze, buchstabe);
}
/**
* Setzt das Kabel in beide Ports ein und fuegt es dem Steckbrett-Array hinzu.
*
* @param port : int : Kabel Nummer, welches am Steckbrett eingesteckt wird.
* @param verbindung : String : Verbindung, welche die vertauschten Buchstaben angibt.
*/
public void setzeSteckbrett(int port, String verbindung) {
if (verbindung.equals("")) {
verbindung = " ";
}
this.hardware.getSteckbrett().setzeVertauschung(port, verbindung.charAt(0), verbindung.charAt(1));
}
//endregion
//region fetch Funktionen
/**
* Gibt die Ringstellungen aus dem Codebuch zurueck.
*
* @return int[] : Array mit den Ringstellungen der drei eingesetzten Walzen.
*/
public int[] fetchRingstellung() {
return this.codebuch.getRingstellung();
}
/**
* Gibt die Walzennummer aus dem Codebuch zurueck.
*
* @return int[] : Array mit den Nummern der drei eingesetzten Walzen.
*/
public int[] fetchWalzenNr() {
return this.codebuch.getWalzenlage();
}
/**
* Gibt die Steckverbindungen aus dem Codebuch zurueck.
*
* @return char[][] : Array mit den gesteckten Verbindungen im Steckbrett.
*/
public char[][] fetchSteckverbindungen() {
return this.codebuch.getSteckverbindung();
}
/**
* Gibt die aktuellen Buchstaben auf den Walzen zurueck.
*
* @return char[] : Walzen Array mit der aktuellen Positionen.
*/
public char[] fetchWalzen() {
char[] walzen = new char[3];
walzen[0] = this.hardware.getWalzen()[0].getPosition();
walzen[1] = this.hardware.getWalzen()[1].getPosition();
walzen[2] = this.hardware.getWalzen()[2].getPosition();
return walzen;
}
/**
* Ueberprueft welche Buchstaben noch zur Vertauschung verfuegbar sind.
*
* @param port: Zahl zwischen 0-9: entspricht der Kabelnummer.
* @return String: liefert einen String mit den verfuegbaren Buchstaben zurueck.
*/
public String fetchVerfuegbareBuchstaben(int port) {
return this.hardware.getSteckbrett().fetchVerfuegbareBuchstaben(port);
}
/**
* Gibt die Walzennummer einer Walze auf Position (walzePos) zurück
*
* @param walzePos : int : Position der Walze
* @return int : Nummer der eingesetzten Walze
*/
public int fetchWalzenNr(int walzePos) {
return this.hardware.getWalzen()[walzePos].getWalzenNr();
}
//endregion
//region codierer
/**
* Hier wird ein einzelner Buchstabe verschluesselt.
* Man muss hier ebenfalls mitgeben, ob der codierte String in "nachricht" gespeichert werden soll oder nicht.
* In der Regel ist dies der Fall.
*
* @param buchstabe : char : Der zu codierende Buchstabe.
* @param save : boolean : Nachricht speichern oder nicht.
* @return char : Der codierte Buchstabe.
*/
public char codiere(char buchstabe, boolean save) {
char codiert = this.hardware.codiere(buchstabe);
if (save) {
this.nachricht += codiert;
}
return codiert;
}
/**
* Codiert den uebergebenen String.
* Man muss hier ebenfalls mitgeben, ob der codierte String in "nachricht" gespeichert werden soll oder nicht.
* In der Regel ist dies der Fall.
*
* @param klartext : String : Der zu codierende Text.
* @param save : boolean : Nachricht speichern oder nicht.
* @return String : Der codierte Text zusaetzlich als Rueckgabe.
*/
public String codiere(String klartext, boolean save) {
StringBuilder sb = new StringBuilder();
for (char buchstabe : klartext.toCharArray()) {
sb.append(this.codiere(buchstabe, save));
}
return sb.toString();
}
/**
* Diese Funktion erwartet als (codierteNachricht) eine korrekte Enigma-Nachricht.
* Ihr muss auch der Tag der Codierung mitgegeben werden. Dieser weiss dein Funker im Funkraum.
* In der Regel ist dies der Tag des Nachrichtenempfangs.
*
* @param codierteNachricht : String : Enigma-codierte Nachricht.
* @param tag : int : Tag der Nachricht.
* @return String : decodierte Nachricht.
*/
private String decodiere(String codierteNachricht, int tag) {
// Hardware reseten und Tageseinstellungen aus dem Codebuch laden
this.codebuch.fetchTagesschluessel(tag);
this.initialisiereHardware();
// Nachricht splitten mit whitespace als delimiter
String[] nachricht = codierteNachricht.split(" ");
StringBuilder sb = new StringBuilder();
// Uhrzeit und Zeichenanzahl der Nachricht
sb.append(nachricht[0]).append(" ");
sb.append(nachricht[1]).append(" ");
// Spruchschluessel
String spruchschluessel = this.decodiereString(nachricht[2]);
sb.append(spruchschluessel).append(" ");
sb.append(this.decodiereString(nachricht[3])).append(" ");
// Walzen neu einstellen mit dem Spruchschluessel
this.hardware.setzePosition(0, spruchschluessel.charAt(0));
this.hardware.setzePosition(1, spruchschluessel.charAt(1));
this.hardware.setzePosition(2, spruchschluessel.charAt(2));
// Nachricht decodieren
sb.append(this.decodiereString(nachricht[4]));
return sb.toString();
}
/**
* Zerlegt den uebergebenen String in einen char-Array und decodiert jedes Zeichen.
* Der String wird dann decodiert zurueckgegeben.
*
* @param nachricht : String : Der zu decodierende Text.
* @return String : Der decodierte Text.
*/
private String decodiereString(String nachricht) {
StringBuilder sb = new StringBuilder();
for (char buchstabe : nachricht.toCharArray()) {
if (buchstabe > 0) {
sb.append(this.hardware.codiere(buchstabe));
}
}
return sb.toString();
}
//endregion
//region Sonstige
/**
* Liest aus der empfangenen Nachricht den Spruchschluessel aus und gibt ihn zurueck.
*
* @param empfangeneNachricht : String : Die empfangene Nachricht als String.
* @return String : Der Spruchschluessel, mit welcher die Nachricht codiert wurde.
*/
public String empfangenerSpruchschluessel(String empfangeneNachricht) {
String[] nachricht = empfangeneNachricht.split(" ");
return nachricht[2];
}
/**
* Loescht das letzte Zeichen aus der Nachricht und dreht die Walzen eine Position zurueck.
*/
public void letztesZeichenLoeschen() {
this.hardware.dreheWalzen(-1);
this.nachricht = this.nachricht.substring(0, this.nachricht.length() - 1);
}
//endregion
//endregion
//region Getter
/**
* Liest die Kenngruppe aus, welche die Maschine gerade besitzt. Frueher war dies eine eindeutige Nummer,
* die einer Einheit zugewiesen war. Wir hinterlegen hier einen Benutzernamen.
*
* @return String : Kenngruppe
*/
public String getKenngruppe() {
return kenngruppe;
}
/**
* Der Spruchschluessel wird, zur internen Verwendung, auch im Klartext gespeichert.
* Wir brauchen diesen dann zum Codieren der eigentlichen Nachricht.
*
* @return String : Der Klartext des Spruchschluessels
*/
public String getSpruchschluessel() {
return this.spruchschluessel;
}
//endregion
}
package projekt.enigma.model;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import projekt.enigma.App;
/**
* In dieser Klasse werden Fehler behandelt und an den User/Admin/Entwickler ausgegeben.
*/
public class Fehler {
/**
* Konstanten die anzeigen ob es sich um eine Funktion oder um eine Nachricht handelt.
*/
private static final String FUNCTION_PREFIX = "- ";
private static final String MESSAGE_PREFIX = "--> ";
/**
* Zeige Fehler Dialog
*
* @param type : String : Art der Meldung (warning/information/error)
* @param subject : String : Titel des Dialoges
* @param message : String : Nachricht der Meldung
*/
public void showErrorDialog(String type, String subject, String message) {
Alert alert;
new Fehler().debug(this.getClass().getName() + "."
+ new Throwable().getStackTrace()[0].getMethodName(), true);
/* Der Titel darf auch als leerer String uebergeben werden, dann wird ein Default gesetzt */
if (subject.equals("")) {
subject = "Es ist ein Fehler aufgetreten";
}
/* Welcher Fehler Typ wurde uebergeben? */
switch (type) {
case "warning":
alert = new Alert(AlertType.WARNING);
break;
case "info":
alert = new Alert(AlertType.INFORMATION);
break;
case "error":
alert = new Alert(AlertType.ERROR);
break;
default:
alert = new Alert(AlertType.NONE);
}
//Anzeige des Alerts definieren
alert.setTitle(subject);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
/**
* Unter zuhilfenahme dieser Funktion koennen Debug Meldungen auf der Konsole ausgegeben werden,
* wenn in der App.java der Getter getDebug einen int > 0 zurueck gibt.
* Ueber diesen Getter kann man steuern ob Meldungen in der Konsole angezeigt werden sollen oder nicht.
*
* @param message : String : Nachricht
* @param isFunction : boolean : Gibt an ob ein Funktionsname uebergeben wird oder eine Debug Meldung
*/
public void debug(String message, boolean isFunction) {
if (App.getDebug() != 0) {
if (isFunction) {
System.out.println(FUNCTION_PREFIX + message);
} else {
System.out.println(MESSAGE_PREFIX + message);
}
}
}
/**
* Unter Zuhilfenahme dieser Funktion koennen Debug Meldungen auf der Konsole ausgegeben werden,
* wenn in der App.java der Getter getDebug einen int > 0 zurueck gibt.
* Ueber diesen Getter kann man steuern ob Meldungen in der Konsole angezeigt werden sollen oder nicht.
*
* @param message : String : Nachricht
* @param isFunction : boolean : Gibt an ob ein Funktionsname uebergeben wird oder eine Debug Meldung.
*/
public void debug(String message, boolean isFunction, int debugLevel) {
if (App.getDebug() != 0 && (App.getDebug() >= debugLevel || App.getDebug() == 3)) {
if (isFunction) {
System.out.println(FUNCTION_PREFIX + message);
} else {
System.out.println(MESSAGE_PREFIX + message);
}
}
}
}
\ No newline at end of file
package projekt.enigma.model;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
/**
* Hier sitzt der Funker.
* Der Funkraum kann Funksprueche empfangen und senden.
* Hierfuer wird eine Verbindung zu einem externen Service aufgebaut.
* Dieser Servive erwartet die Nachrichten im JSON Format. Dazu wird ein k als Kenngruppe
* (Benutzername) uebergeben und falls eine Nachricht gesendet werden soll, zusaetzlich ein m mit der Nachricht.
* Beides wird als String gesendet.
*/
public class Funkraum {
/**
* Zum Empfangen liefert der Server, anstatt der Kenngruppe (k), den Empfangstag (t) der Nachricht mit, damit man
* die Grundeinstellungen aus dem Codebuch, für diesen Tag, raussuchen kann.
* {'m': 'Hello world', 't': '26'}
*
* @param kenngruppe : String : Kenngruppe dieser Enigma
* @return funkspruch : String[] : String Array wobei Index 0 dem Empfangstag entspricht und Index 1
* der empfangenen Nachricht.
* @throws NullPointerException : Exception : Keine Nachricht vorhanden.
*/
public String[] empfangeFunkspruch(String kenngruppe) {
String[] funkspruch = new String[2];
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://enigma.itstall.de/");
try {
// Anfrage Parameter und Encoding setzen
List<NameValuePair> params = new ArrayList<>(2);
params.add(new BasicNameValuePair("k", kenngruppe));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// POST Request ausfuehren und Rueckgabe verarbeiten
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
JSONObject result = new JSONObject(reader.readLine());
if (!result.getString("m").isEmpty()) {
funkspruch[0] = result.getString("t");
funkspruch[1] = result.getString("m");
}
}
} catch (UnsupportedEncodingException e) {
new Fehler().showErrorDialog("error", "Encoding wird nicht unterstützt",
"Kommunikation mit dem Feind wird als Landesverrat bestraft");
} catch (IOException e) {
new Fehler().showErrorDialog("error", "HTTP Post war nicht erfolgreich",
"Bitte wenden Sie sich an ihren Vorgesetzten.");
} catch (NullPointerException e) {
new Fehler().showErrorDialog("info", "Keiner schreibt dir...",
"Es liegen keine neuen Nachrichten im Funkraum für Sie vor.");
}
return funkspruch;
}
/**
* Dem Service senden wir unsere Nachricht als POST Parameter (m) und unsere Kenngruppe (k).
* Dieser nimmt die Daten entgegen und hierlerlegt sie auf seinem Stapel (Datenbank) von dem die Nachrichten
* irgendwann, auf Anfrage, wieder abgerufen werden koennen.
* <br>
* Darauf antwortet der Server mit einem JSON Object in dem das Ergebnis der Anfrage zu sehen ist.
* {'result': 200}
* <br>
* Die 200 heisst hier, dass alles erfolgreich durchgefuehrt werden konnte. Steht hier etwas anderes, ist ein Fehler
* aufgetreten und die Anfrage war nicht erfolgreich.
* In letzterem Fall sollte eine Meldung an den Benutzer ausgegeben werden und ggf. spaeter erneut versucht werden.
*
* @param funkspruch : String : Der zu sendende Funkspruch
* @param kenngruppe : String : Die Kenngruppe dieser Engima
* @throws IOException : Exception : Funkspruch konnte nicht gesendet werden
*/
public void sendeFunkspruch(String funkspruch, String kenngruppe) throws IOException {
HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("https://enigma.itstall.de/");
// Anfrage Parameter und Encoding setzen
List<NameValuePair> params = new ArrayList<>(2);
params.add(new BasicNameValuePair("k", kenngruppe));
params.add(new BasicNameValuePair("m", funkspruch));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
// POST Request ausfuehren und Rueckgabe verarbeiten
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
JSONObject result = new JSONObject(reader.readLine());
if (result.getInt("result") != 200) {
new Fehler().showErrorDialog("error", "HTTP Exception",
"Der andere Funker mag deine Nachricht nicht. "
+ "Rüge ihn wenn du ihn wieder siehst...");
}
}
}
}