Enigma hinzugefügt
parent
41eeed22bb
commit
56582e5399
|
@ -0,0 +1,127 @@
|
||||||
|
package Enigma;
|
||||||
|
|
||||||
|
public class Enigma {
|
||||||
|
|
||||||
|
// 5 Walzen (https://de.wikipedia.org/wiki/Enigma_(Maschine)#Aufbau)
|
||||||
|
private final String[] W = {
|
||||||
|
"EKMFLGDQVZNTOWYHXUSPAIBRCJ",
|
||||||
|
"AJDKSIRUXBLHWTMCQGZNPYFVOE",
|
||||||
|
"BDFHJLCPRTXVZNYEIWGAKMUSQO",
|
||||||
|
"ESOVPZJAYQUIRHXLNFTGKDCMWB",
|
||||||
|
"VZBRGITYUPSDNHLXAWMJQOFECK"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3 Umkehrwalzen (https://de.wikipedia.org/wiki/Enigma_(Maschine)#Aufbau)
|
||||||
|
private final String[] UKW = {
|
||||||
|
"EJMZALYXVBWFCRQUONTSPIKHGD",
|
||||||
|
"YRUHQSLDPXNGOKMIEBFZCWVJAT",
|
||||||
|
"FVPJIAOYEDRZXWGCTKUQSBNMHL"
|
||||||
|
};
|
||||||
|
|
||||||
|
private Walze[] w;
|
||||||
|
private Walze ukw;
|
||||||
|
private Steckbrett s;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param config Leerzeichen getrennter String:
|
||||||
|
* 1. Anzahl Walzen
|
||||||
|
* 2. Walzenkonfiguration jeweils:
|
||||||
|
* 2.1. Walzennummer (0-5)
|
||||||
|
* 2.2. Walzenring (0-25)
|
||||||
|
* 2.3. Walzenstellung (0-25)
|
||||||
|
* 3. Umkehrwalze (0-2)
|
||||||
|
* 4. Steckbrett, leerzeichengetrennt Buchstabenpaare
|
||||||
|
*
|
||||||
|
* Achtung: noch keine Fehlerbehandlung! Steckbrett -> Buchstaben dürfen nicht doppelt vorkommen!
|
||||||
|
*/
|
||||||
|
public Enigma(String config) {
|
||||||
|
String[] c = config.split(" ");
|
||||||
|
|
||||||
|
int walzenanzahl = Integer.parseInt(c[0]);
|
||||||
|
|
||||||
|
this.w = new Walze[walzenanzahl];
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
for (int j = 0; j < walzenanzahl; j++) {
|
||||||
|
int walze = Integer.parseInt(c[i++]);
|
||||||
|
int ring = Integer.parseInt(c[i++]);
|
||||||
|
int stellung = Integer.parseInt(c[i++]);
|
||||||
|
|
||||||
|
this.w[j] = new Walze(this.W[walze], ring, stellung);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ukw = Integer.parseInt(c[i++]);
|
||||||
|
this.ukw = new Walze(this.UKW[ukw], 0, 0);
|
||||||
|
|
||||||
|
String s = "";
|
||||||
|
for (int j = i; j < c.length; j++) {
|
||||||
|
if (j != i) s += " ";
|
||||||
|
s += c[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.s = new Steckbrett(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param s
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String crypt(String s) {
|
||||||
|
return this.crypt(s, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ver- und entschlüsselt einen Text
|
||||||
|
* @param s String der verschlüsselt werden soll
|
||||||
|
* @param hidespecial sollen Zeichen, die keine Buchstaben sind ausgeblendet werden?
|
||||||
|
* @return ver- bzw. entschlüsselter Text
|
||||||
|
*/
|
||||||
|
public String crypt(String s, boolean hidespecial) {
|
||||||
|
String ret = "";
|
||||||
|
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
// einzelner Buchstabe aus Text
|
||||||
|
char c = s.toUpperCase().charAt(i);
|
||||||
|
|
||||||
|
// wenn kein Buchstabe, dann ggf. überspringen oder unverschlüsselt übernehmen
|
||||||
|
if (c < 'A' || c > 'Z') {
|
||||||
|
if (!hidespecial) ret += c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Steckbrett durchlaufen
|
||||||
|
c = this.s.in(c);
|
||||||
|
|
||||||
|
// Walzen in Hinrichtung durchlaufen
|
||||||
|
for (int w = 0; w < this.w.length; w++) {
|
||||||
|
c = this.w[w].in(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Umkehrwalze durchlaufen
|
||||||
|
c = this.ukw.in(c);
|
||||||
|
|
||||||
|
// Walzen in Rückrichtung durchlaufen
|
||||||
|
for (int w = this.w.length - 1; w >= 0; w--) {
|
||||||
|
c = this.w[w].out(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Steckbrett nochmals durchlaufen
|
||||||
|
c = this.s.in(c);
|
||||||
|
|
||||||
|
// verschlüsselter Buchstabe an Ergebnis anhängen
|
||||||
|
ret += c;
|
||||||
|
|
||||||
|
// Walzen weiter drehen
|
||||||
|
for (int w = 0; w < this.w.length; w++) {
|
||||||
|
if (!this.w[w].next()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// zur besseren Übersicht Leerzeichen einfügen
|
||||||
|
if (i % 5 == 4 && hidespecial) ret += ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package Enigma;
|
||||||
|
|
||||||
|
public class Start {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
// 3 -> 3 Walzen
|
||||||
|
// 0 0 0 -> 1. Walze Nr 0, Ring 0, Ausgangsstellung 0
|
||||||
|
// 2 0 0 -> 2. Walze Nr 2, Ring 0, Ausgangsstellung 0
|
||||||
|
// 1 0 0 -> 3. Walze Nr 1, Ring 0, Ausgangsstellung 0
|
||||||
|
// 0 -> Umkehrwalze Nr 0
|
||||||
|
// AG EP QS XY ZD -> Steckfeldkonfiguration
|
||||||
|
String config = "3 0 0 0 2 0 0 1 0 0 0 AG EP QS XY ZD";
|
||||||
|
|
||||||
|
Enigma e = new Enigma(config);
|
||||||
|
System.out.println(e.crypt("Informatik ist Toll!", false));
|
||||||
|
|
||||||
|
// Zurück auf Ausgansposition
|
||||||
|
e = new Enigma(config);
|
||||||
|
// 2. Parameter false -> Sonderzeichen unverschlüsselt kopieren
|
||||||
|
System.out.println(e.crypt("WOQNWNRZGW XHU FKJD!", false));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package Enigma;
|
||||||
|
|
||||||
|
public class Steckbrett {
|
||||||
|
|
||||||
|
private int[] vertauschung;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steckbrett anlegen
|
||||||
|
* @param v leerzeichengetrennte Buchstabenpaare, die vertauscht werden sollen, Großbuchstaben! Keine doppelten Buchstaben verwenden!
|
||||||
|
*/
|
||||||
|
public Steckbrett(String v) {
|
||||||
|
// Vertauschungs-Liste anlegen
|
||||||
|
this.vertauschung = new int[26];
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
// Standardmäßig: keine Vertauschung
|
||||||
|
this.vertauschung[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] tmp = v.split(" ");
|
||||||
|
|
||||||
|
for (int i = 0; i < tmp.length; i++) {
|
||||||
|
if (tmp[i].length() != 2) continue;
|
||||||
|
|
||||||
|
// lege bei beiden Buchstaben den vertauschten Index ab
|
||||||
|
int i1 = tmp[i].charAt(0) - 'A';
|
||||||
|
int i2 = tmp[i].charAt(1) - 'A';
|
||||||
|
|
||||||
|
this.vertauschung[i1] = i2;
|
||||||
|
this.vertauschung[i2] = i1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Durchläuft das Steckbrett
|
||||||
|
* @param c Eingabebuchstabe
|
||||||
|
* @return Ausgabebuchstabe
|
||||||
|
*/
|
||||||
|
public char in(char c) {
|
||||||
|
int index = c - 'A';
|
||||||
|
|
||||||
|
return (char)(this.vertauschung[index] + 'A');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package Enigma;
|
||||||
|
|
||||||
|
public class Walze {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private int[] verschiebungen;
|
||||||
|
|
||||||
|
private int ring;
|
||||||
|
private int stellung;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* legt eine Walze an
|
||||||
|
* @param code auf welche Buchstaben das Alphabet abgebildet wird
|
||||||
|
* @param ring bei welcher Stellung die nächste Walze ausgelöst werden soll
|
||||||
|
* @param stellung Ausgangsstellung
|
||||||
|
*/
|
||||||
|
public Walze(String code, int ring, int stellung) {
|
||||||
|
this.code = code;
|
||||||
|
this.verschiebungen = new int[code.length()];
|
||||||
|
for (int i = 0; i < code.length(); i++) {
|
||||||
|
this.verschiebungen[i] = code.charAt(i) - 'A' - i;
|
||||||
|
|
||||||
|
// System.out.print(this.verschiebungen[i] + " , ");
|
||||||
|
}
|
||||||
|
// System.out.println();
|
||||||
|
|
||||||
|
this.ring = ring % 26;
|
||||||
|
this.stellung = stellung % 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dreht die Walze eine Stellung weiter
|
||||||
|
* @return true, wenn nächste Walze gedreht werden soll
|
||||||
|
*/
|
||||||
|
public boolean next() {
|
||||||
|
stellung = (stellung + 1) % 26;
|
||||||
|
return stellung == ring;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertauscht die Buchstaben in Eingangsrichtung
|
||||||
|
* @param c Eingangsbuchstabe
|
||||||
|
* @return Ausgangsbuchstabe
|
||||||
|
*/
|
||||||
|
public char in(char c) {
|
||||||
|
int index = c - 'A';
|
||||||
|
int verschiebung = this.verschiebungen[(index + stellung) % 26];
|
||||||
|
|
||||||
|
return (char)((index + 26 + verschiebung) % 26 + 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertauscht die Buchstaben in Rückrichtung
|
||||||
|
* @param c Eingangsbuchstabe
|
||||||
|
* @return Ausgangsbuchstabe
|
||||||
|
*/
|
||||||
|
public char out(char c) {
|
||||||
|
int index = this.code.indexOf((c - 'A' + stellung) % 26 + 'A');
|
||||||
|
int verschiebung = -this.verschiebungen[(index) % 26];
|
||||||
|
|
||||||
|
return (char)((c - 'A' + 26 + verschiebung) % 26 + 'A');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue