# Cäsar Verschlüsselung



## JoeB (15. Mrz 2011)

Hallo,

ich habe ein Problem. Und zwar habe ich einen Code für die Cäsar Verschlüsselung geschrieben. Funktioniert auch sehr gut, wenn der Key bei 2 liegt...allerdings sollte der Key bei 17 liegen und das klappt nicht. Vielleicht findet ja jemand den Fehler...Danke schon mal!


```
import java.io.*;
import java.text.*;
import java.util.*;

public class caesar{    
	
	public static void main(String[] args){
    
	StringBuffer output = new StringBuffer();
	
      try { 
        InputStream in = new BufferedInputStream( new FileInputStream(args[0]) );
		byte[] b = new byte[4096];
        try { 
		  //int c = in.read();
          for(int c; (c = in.read(b)) != -1;) {
			output.append(new String(b, 0, c));
			//System.out.write( c );
		  }  
        } 
        finally { 
          in.close();
        } 
      } 
      catch ( IOException e ) { 
        System.err.println( "cat: Fehler beim Verarbeiten von " + args[0] ); 
        System.exit( 1 ); 
      }  

	// Encryption Key
	int ek = 2;
	
	// Decryption Key
	//int dekey = -2;
	int dk = Integer.parseInt(args[1]);
	caesar input = new caesar();
	
	System.out.println("Verschluesselter Text: ");
	System.out.println(output.toString());
	System.out.println("Entschluesselter Text: ");
	System.out.println(input.crypt(output.toString(), dk));
	}	
		
	public String crypt(String input, int key) {
        char[] letters = input.toCharArray();
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < letters.length; ++i) {
            if (letters[i] >= 'A' && letters[i] < 'A' + 26)
                letters[i] = (char) (
               ((letters[i] + key - 'A') % 26) + 'A');
            result.append(letters[i]);
        }
        return result.toString();
    }
}
```


----------



## HoaX (15. Mrz 2011)

Also egal was ich übergebe, ich bekomme immer die selbe Ausgabe. Und sowohl bei verschüsselt und entschlüsselt wird das selbe angezeigt.

Klassennamen schreibt man groß!

Nachtrag 1: Das Einlesen der Datei ist umständlich, nimm besser einen FileReader + BufferedReader, dann kannst du mit readLine() ganze Zeilen fertig einlesen und musst nicht ständig einen neuen String erstellen. Ansonsten hat StringBuffer iirc auch eine append-Methode welche char als Parameter nimmt.

Nachtrag 2: Das es nicht ging lag wohl daran, dass meine Datei nur kleine Buchstaben enthielt.

Nachtrag 3: Auch mit -2 als Dekoder geht es nicht, wenn man ABCDEF in der Datei stehen hat.


----------



## HoaX (15. Mrz 2011)

Das Problem ist klar dein Modulo.

Sobald letter_ - 'A' + key eine Ergebnis kleiner 0 liefert funktioniert dein Code nicht, da -2 % 26 == -2 gilt in Java.

Hättest du aber auch selbst herausfinden können, wenn du deine tolle Rechnung mal in seine Teilschritte zerlegt hättest und dann die Zwischenergebnisse betrachtet hättest. _


----------



## Dow Jones (15. Mrz 2011)

HoaX hat gesagt.:


> Sobald letter_ - 'A' + key eine Ergebnis kleiner 0 liefert funktioniert dein Code nicht, da -2 % 26 == -2 gilt in Java._


_
Ah, interessant zu wissen.   Leider erklärt das aber nicht weshalb es mit einem Key von 17 nicht funktioniert (siehe Anfangsposting). Wobei - bei mir klappt's. 

Code per copy & paste übernommen, Ergebnis:


		Code:In die Zwischenablage kopieren


> cat caesar.txt
ABCDEF

> java Caesar caesar.txt 2
Verschluesselter Text:
ABCDEF

Entschluesselter Text:
CDEFGH


> java Caesar caesar.txt 17
Verschluesselter Text:
ABCDEF

Entschluesselter Text:
RSTUVW

Schaut doch richtig aus, oder?_


----------



## HoaX (16. Mrz 2011)

1) F == 6
2) 6 + 17 = 23
3) 23 % 26 = 23

Klar gehts. Trage eine negative Zahl ein und es geht nicht. Du musst schon auch versuchen meine Antwort zu verstehen


----------



## Dow Jones (16. Mrz 2011)

Naja, deine Antwort habe ich (hoffentlich) schon verstanden. Was ich aber nicht verstanden habe ist wie sie zur Frage passt... 

1) Die Modulorechnung wird nur bei Großbuchstaben durchgeführt
2) für Großbuchstaben liefert letter_ - 'A' + key immer einen positiven Wert, sofern key >= 0 ist
3) von negativen Keys war nie die Rede. Der TS fragte eher weshalb es mit einem key von 17 nicht funktioniert

Wie gesagt, bei mir klappt's prima. Mache ich was falsch? _


----------



## HoaX (16. Mrz 2011)

Dann nimm doch mal ABCXYZ und probiere es nochmal, Ver- _und_ entschlüsseln!

Es gilt ja Entschlüsselungskey = Verschlüsselungskey * (-1).
Ich ging in Anlehnung an den gezeigten Code davon aus, dass der Verschlüsselungskey > 0 ist (siehe auskommentierter Code).
Wenn du davon ausgehst dass der Entschlüsselungskey > 0 ist, dann mag das soweit funktionieren, aber dafür geht dann halt die Verschlüsselung nicht ...


----------



## Dow Jones (16. Mrz 2011)

Ach sooo... Okay, soweit hatte ich nicht gedacht. 
Ich hätte erwartet das es neben crypt() noch eine Methode decrypt() geben wird, oder das der key für die Entschlüsselung durch die Formel 26 - key berechnet wird. Wie auch immer. Es bleibt die Frage wieso der oben angeführte Code beim Threadstarter nicht mit dem Schlüssel 17 funktioniert. Hallo JoeB, magst du dich nochmal dazu äußern oder ist das Thema schon erledigt?


----------



## HoaX (16. Mrz 2011)

Dow Jones hat gesagt.:


> Ach sooo... Okay, soweit hatte ich nicht gedacht.
> Ich hätte erwartet das es neben crypt() noch eine Methode decrypt() geben wird, oder das der key für die Entschlüsselung durch die Formel 26 - key berechnet wird. Wie auch immer. Es bleibt die Frage wieso der oben angeführte Code beim Threadstarter nicht mit dem Schlüssel 17 funktioniert. Hallo JoeB, magst du dich nochmal dazu äußern oder ist das Thema schon erledigt?



Weil er wohl mit 17 den Verschlüsselungskey meint und die Entschlüsselung nicht funktioniert. Er schreibt ja auch dass es mit 2 geht, und im Code ist noch ek = 2 drin und das dekey = -2 auskommentiert.


----------



## Pilschen (3. Jun 2011)

Also, ich möchte keinen neuen Thread eröffnen, also poste ich das mal hier. Zuerst einmal, ich bin blutiger Anfänger, und habe nur eine doofe Info-Lehrerin, die mal wieder viel zu viel verlanget, obwohl sie es selber nicht kann (kein scherz, die ist strohdoof xD).
Zum Problem: wir sollen ein einfaches Caesar-chiffrier programm schreiben, jedoch hab ich keine Ahnung wie man buchstaben vertauscht. Dazu muss man vielleicht noch sagen, dass wir bisher nur sehr simple Sachen gemacht haben (wir machen jetzt seit einem halben Jahr 2 h die Woche Java bei der schlechtesten Lehrerin der Welt, also viel kann da bei halt nich rumkommen...), so wie einfach while und if schleifen auf Knöpfe bezogen o.Ä. (z.B. so was wie if(Knopf.wurdeGedrueckt()){ textfeld.setzeText("Hallo")} und sowas...).
Meine erste idee war es jeden Buchstaben einzelnen als strg zu definieren, und dann mit einer if-schleife an einen verschlüsselungs-knopf gebunden den befehl zu geben, dass alles +3 gerechnet werden soll oder was auch immer, es sich also verschieb, und das ausgabe-textfeld dies dann irgendwie ausgibt.
Ich hab jedoch leider keine Ahnung wie das geht 

Wäre also wirklich super nett, wenn irgendjemand anfängerfreundlich einen befehl erklären könnte, wie so etwas umzusetzen ist.

Im Anhang hab ich mal das geschrieben, was wir bisher haben (Benutzeroberfläche halt), damit ihr mal einen groben Überblick kriegt, wie das ganze aussehen soll. evtl. würde ich es auch mit einer wahlbox machen, wo man einfach nur cryp/decrypt auswählt und damit der entsprechende befehl verbunden ist, aber das ist ja eigentlich egal, ob ich es mit wahlboxen oder mit verschiedenen textfeldern und knöpfen mache.

Ich wäre wirklich extrem dankbar für jedwedige Hilfe


----------



## Lukas95 (3. Jun 2011)

Hallo!

Ich würde das so machen:

Den Benutzer eben um die Eingabe bitten. Dann char für char einlesen und verschlüssen. Das Verschlüsseln machst du am besten indem du mit (so habs ich gemacht) mit switch überprüfst welcher Buchstabe der eingegebene ist und verschlüsselst du den.
Am Besten du speicherst zum verschlüsseln das ganze Alphabet in einem char-array und zählst dann von der Stelle an der der eingegebene Buchstabe zum Beispiel 7 hinauf.
So ich hoffe du verstehst so halbwegs was ich meine.
Hier ist meine Klasse zum Verschlüsseln (ist zwar sicher nicht der Beste Weg aber es funktioniert, solange man nur Großbuchstaben keine Sonderzeichen eingibt ach ja und keine Leerzeichen, aber verschlüsseln tut er):

```
import java.util.Scanner;

public class Verschlüsseln {
	private char[] original = {'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 char[] verschluesselt = {'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', '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'};
	
	char wie(){
		Scanner sc = new Scanner (System.in);
		System.out.print("A wird zu ");
		char wie = sc.next().charAt(0);
		return wie;
	}
	
	void einlesen(){
		Scanner sc = new Scanner (System.in);
		String text = new String();
		Verschlüsseln v = new Verschlüsseln();
		char c;
		char[] textfeld; 
		String text_v = "Der uebersetze Text lautet: ";
		int fall = 0;
	
		
		System.out.println ("Schreibe den Text den du verschluesseln moechtest!");
		System.out.println("ACHTUNG: ohne Leerzeichen, keine Satzzeichen, nur Grossbuchstaben");
		System.out.println ("und keine Umlaute oder \"scharfes S\"");
		text = sc.next();
		c = v.wie(); 
		textfeld = text.toCharArray(); 
		
		switch(c) {
		
		case 'A':
			fall = 0;
			break;
			
		case 'B':			
			fall = 1; 
			break;
			
		case 'C':
			fall = 2;
			break;
			
		case 'D':
			fall = 3;
			break;
			
		case 'E':
			fall = 4;
			break;
			
		case 'F':
			fall = 5;
			break;
			
		case 'G':
			fall = 6;
			break;
			
		case 'H':
			fall = 7;
			break;
			
		case 'I':
			fall = 8;
			break;
			
		case 'J':
			fall = 9 ;
			break;
			
		case 'K':
			fall = 10;
			break;
			
		case 'L': 
			fall = 11;
			break;
			
		case 'M': 
			fall = 12;
			break;
			
		case 'N': 
			fall = 13;
			break;
			
		case 'O':
			fall = 14;
			break;
			
		case 'P': 
			fall = 15;
			break;
			
		case 'Q':
			fall = 16;
			break;
			
		case 'R':
			fall = 17;
			break;
			
		case 'S': 
			fall = 18;
			break;
			
		case 'T': 
			fall = 19;
			break;
			
		case 'U': 
			fall = 20;
			break;
			
		case 'V': 
			fall = 21;
			break;
			
		case 'W': 
			fall = 22;
			break;
			
		case 'X': 
			fall = 23;
			break;
			
		case 'Y':
			fall = 24;
			break;
			
		case 'Z': 
			fall = 25;
			break;
			
		}
		
		for (char ver : textfeld)
		{
		    text_v = text_v + v.verschluesseln(ver, fall);
		}
		
		System.out.println(text_v);
		
		
	}
	
	String verschluesseln(char c, int fall){
		String ver = "";
		for (int i = 0; i < original.length; i++){
			if (c == original[i]){
				ver = ver + verschluesselt[i + fall];
			}
		}
		return ver;
		
	}
}
```


----------



## Pilschen (5. Jun 2011)

Danke erstmal für die Antwort und deine Mühe 
Also, wenn ich das richtig verstehe und lese dann gibt dein Programm das ganze direkt über die Konsole aus, richtig?
D.h. ich bräuchte den ganzen Oberflächen-Mist von mir gar nicht, oder?
Kann ich die Klasse dann einfach so übernehmen und es funktioniert? Wo muss man denn dann den Text eingeben, den man verschlüsseln will? Auch über die Konsole unten oder wie?

Wie du merkst, der Info unterricht war bisher nicht sehr erfolgreich, hehe ;D
Danke für die Geduld


----------



## Lukas95 (5. Jun 2011)

Ja das ganze funktioniert über die Konsole, auch die Eingabe. Du musst noch ein Klasse machen in der sich di Mainmethode drinnen ist und dann ein Objekt von der Klasse Verschlüsseln machen. Und dann einfach noch mit der Referenz auf die Methode einlesen zugreifen. 

Viel Spaß noch im Infounterricht ;-)


----------

