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