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