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