Javakurs/Übungsaufgaben/Cäsar-Chiffre/Musterlösung: Unterschied zwischen den Versionen
< Javakurs | Übungsaufgaben | Cäsar-Chiffre
(Die Seite wurde neu angelegt: „<pre> →Decodes texts having been encoded with caesar: import java.io.*; public class Caesar { public static void main(String arg[]) { ...“) |
|||
(Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt) | |||
Zeile 20: | Zeile 20: | ||
int menuCase; | int menuCase; | ||
− | String text= | + | String text= ""; |
String textState= "nothing loaded"; | String textState= "nothing loaded"; | ||
− | String output= | + | String output= ""; /*will always be shown under menu*/ |
int key; | int key; | ||
Zeile 47: | Zeile 47: | ||
String s= readln(); | String s= readln(); | ||
− | menuCase= Integer. | + | menuCase= Integer.parseInt(s); |
Zeile 91: | Zeile 91: | ||
{ | { | ||
System.out.print("key: "); | System.out.print("key: "); | ||
− | key= Integer. | + | key= Integer.parseInt(readln()); |
text= encryptCaesar(text, key); | text= encryptCaesar(text, key); | ||
Zeile 111: | Zeile 111: | ||
text= decryptCaesar(text, key); | text= decryptCaesar(text, key); | ||
− | output= | + | output= "key is: "+ key; |
textState= "decrypted"; | textState= "decrypted"; | ||
Zeile 122: | Zeile 122: | ||
{ | { | ||
System.out.print("key: "); | System.out.print("key: "); | ||
− | key= Integer. | + | key= Integer.parseInt(readln()); |
text= decryptCaesar(text, key); | text= decryptCaesar(text, key); | ||
Zeile 223: | Zeile 223: | ||
− | String text= | + | String text= ""; |
Zeile 232: | Zeile 232: | ||
BufferedReader buff = new BufferedReader(file); | BufferedReader buff = new BufferedReader(file); | ||
− | |||
− | + | while ( true ) { | |
− | while ( | ||
String line = buff.readLine(); | String line = buff.readLine(); | ||
Zeile 241: | Zeile 239: | ||
if ( null == line ) { | if ( null == line ) { | ||
− | + | break; | |
} else { | } else { | ||
Zeile 272: | Zeile 270: | ||
String originLowCase= origin.toLowerCase(); | String originLowCase= origin.toLowerCase(); | ||
− | String text= | + | String text= ""; |
Zeile 278: | Zeile 276: | ||
/* filtering signs 'a' to 'z' using ASCII numbers */ | /* filtering signs 'a' to 'z' using ASCII numbers */ | ||
− | if ( ( | + | if ( (originLowCase.charAt(i)>= 'a') |
− | && ( | + | && (originLowCase.charAt(i)<= 'z') ) |
text+= originLowCase.charAt(i); | text+= originLowCase.charAt(i); | ||
Zeile 300: | Zeile 298: | ||
* number of chars in text*/ | * number of chars in text*/ | ||
− | int | + | int[] chr= new int[27]; |
Zeile 306: | Zeile 304: | ||
for ( int j= 0; j< text.length(); j++ ) { | for ( int j= 0; j< text.length(); j++ ) { | ||
− | chr[ | + | chr[ text.charAt(j) - 'a' ]++; |
chr[26]++; | chr[26]++; | ||
Zeile 331: | Zeile 329: | ||
* number of chars in text*/ | * number of chars in text*/ | ||
− | int | + | int[] chr= frequencyAnalysis(text); |
Zeile 514: | Zeile 512: | ||
− | String text= | + | String text= ""; |
/* number of occurence of most frequent char: */ | /* number of occurence of most frequent char: */ | ||
Zeile 522: | Zeile 520: | ||
− | char | + | char[] en= {'e','t','a',}; //most frequent letters in english |
− | char | + | char[] ge= {'e','n','i',}; //most frequent letters in german |
Zeile 558: | Zeile 556: | ||
/* define most frequent char */ | /* define most frequent char */ | ||
− | int | + | int[] chr= frequencyAnalysis(origin); |
Zeile 583: | Zeile 581: | ||
/*assumed char causes certain displacement */ | /*assumed char causes certain displacement */ | ||
− | displacement= (mostFrequentChr+ | + | displacement= (mostFrequentChr+'a') - (int) en[k] ; |
} else { | } else { | ||
− | displacement= (mostFrequentChr+ | + | displacement= (mostFrequentChr+'a') - (int) ge[k] ; |
} | } | ||
Zeile 630: | Zeile 628: | ||
public static String encryptCaesar( String text, int key ) { | public static String encryptCaesar( String text, int key ) { | ||
− | return | + | return modifyText(text, key); |
} | } | ||
public static String decryptCaesar( String text, int key ) { | public static String decryptCaesar( String text, int key ) { | ||
− | key= | + | key*= -1; |
− | return | + | return modifyText(text, key); |
} | } | ||
public static String modifyText( String text, int key ) { | public static String modifyText( String text, int key ) { | ||
− | String encrypted= | + | String encrypted= ""; |
− | key= | + | key%= 26; |
− | |||
− | |||
− | |||
for ( int i= 0; i< text.length(); i++ ) { | for ( int i= 0; i< text.length(); i++ ) { | ||
− | currentChar= (int) text.charAt(i); | + | int currentChar= (int) text.charAt(i); |
− | code= currentChar; | + | int code= currentChar; |
/*lower case letters*/ | /*lower case letters*/ |
Aktuelle Version vom 27. Mai 2011, 09:13 Uhr
/* Decodes texts having been encoded with caesar */ import java.io.*; public class Caesar { public static void main(String arg[]) { int menuCase; String text= ""; String textState= "nothing loaded"; String output= ""; /*will always be shown under menu*/ int key; do { System.out.println("[1] load text"); System.out.println("[2] show text"); System.out.println("[3] save text"); System.out.println("[4] encrypt text"); System.out.println("[5] decrypt text without key"); System.out.println("[6] decrypt text with key"); System.out.println("[7] quit"); System.out.println( ); System.out.println("text state: ["+ textState +"]"); System.out.println( ); System.out.println( output ); System.out.print("input: "); String s= readln(); menuCase= Integer.parseInt(s); switch (menuCase) { case 1: { System.out.print("filename: "); String fileIn= readln(); text= readFile(fileIn); output = ""; textState= "loaded"; break; } case 2: { output= text; break; } case 3: { System.out.print("filename: "); String fileName= readln(); String[] fileToSave= {text}; writeArrayToFile( fileName, fileToSave ); output = ""; break; } case 4: { System.out.print("key: "); key= Integer.parseInt(readln()); text= encryptCaesar(text, key); output = ""; textState= "encrypted"; break; } case 5: { if( determineKoinzidenzindex(text) < 0.06 ) { output= "Text might not be Caesar encrypted! "; } key= findKeyCaesar(text); text= decryptCaesar(text, key); output= "key is: "+ key; textState= "decrypted"; break; } case 6: { System.out.print("key: "); key= Integer.parseInt(readln()); text= decryptCaesar(text, key); output = ""; textState= "decrypted"; break; } }//switch }while(menuCase!=7); } //main /* reads in a text from console */ public static String readln() { BufferedReader consoleLine = new BufferedReader(new InputStreamReader(System.in)); String input = null; try { input = consoleLine.readLine(); } catch (IOException e) { e.printStackTrace(); } return input; } /** * Schreibt einen String-Array in eine Datei. * @param filename : Pfad zu der Datei in Form eines Strings, also z.B. "hallo.txt" oder "/etc/fstab", ... * @param data String-Array: welches in die angegebene Datei geschrieben werden soll. * @return */ public static boolean writeArrayToFile(String filename, String[] data ) { BufferedWriter bufferedWriter; try { // Datei zum schreiben oeffnen bufferedWriter= new BufferedWriter( new OutputStreamWriter( new FileOutputStream(filename)) ); // Array Elementenweise in Datei schreiben for (int i = 0; i < data.length; i++) { bufferedWriter.write(data[i]); bufferedWriter.newLine(); } bufferedWriter.flush(); } catch (Exception e) { // Fehlerbehandlung e.printStackTrace(); return false; } return true; } /* reads in a text */ public static String readFile( String fileName ) { String text= ""; try { FileReader file = new FileReader (fileName); BufferedReader buff = new BufferedReader(file); while ( true ) { String line = buff.readLine(); if ( null == line ) { break; } else { text+= line; } } buff.close(); } catch (IOException e) { System.out.println( e.toString() ); } return text; } /* takes out punctuation and sets all letters to lower case */ public static String takeOutPunctuation( String origin ) { String originLowCase= origin.toLowerCase(); String text= ""; for ( int i= 0; i<originLowCase.length(); i++ ) { /* filtering signs 'a' to 'z' using ASCII numbers */ if ( (originLowCase.charAt(i)>= 'a') && (originLowCase.charAt(i)<= 'z') ) text+= originLowCase.charAt(i); } return text; } public static int[] frequencyAnalysis( String text ) { /* holds frequency of chars a-z, last digit (index 26) is total * number of chars in text*/ int[] chr= new int[27]; for ( int j= 0; j< text.length(); j++ ) { chr[ text.charAt(j) - 'a' ]++; chr[26]++; } return chr; } /*see also: http://de.wikipedia.org/wiki/Koinzidenzindex */ public static double determineKoinzidenzindex( String text ) { text= takeOutPunctuation( text ); int cnt= 0; double kindex= 0; /* holds frequency of chars a-z, last digit (index 26) is total * number of chars in text*/ int[] chr= frequencyAnalysis(text); /* chr.length-1 remember: last digit holds number of chars */ for ( int k= 0; k< chr.length-1; k++ ) { kindex+= ( ((double) chr[k]/chr[26])*((double) chr[k]/chr[26])); } return kindex; } /* count the number of nigramms and trigramms in a german text*/ public static int germanText( String text ) { int cntbitri= 0; //counter for bi- and trigramms /* count bigramms */ for ( int i= 0; i< text.length()-1; i++ ) { if ( (text.substring(i, i+2).equals("er")) ||(text.substring(i, i+2).equals("en")) ||(text.substring(i, i+2).equals("ch")) ||(text.substring(i, i+2).equals("de")) ||(text.substring(i, i+2).equals("ei")) ||(text.substring(i, i+2).equals("nd")) ||(text.substring(i, i+2).equals("te")) ||(text.substring(i, i+2).equals("in")) ||(text.substring(i, i+2).equals("ie")) ||(text.substring(i, i+2).equals("ge")) ) cntbitri++; } /* count trigramms */ for ( int i= 0; i< text.length()-2; i++ ) { if ( (text.substring(i, i+3).equals("ein")) ||(text.substring(i, i+3).equals("ich")) ||(text.substring(i, i+3).equals("nde")) ||(text.substring(i, i+3).equals("die")) ||(text.substring(i, i+3).equals("und")) ||(text.substring(i, i+3).equals("der")) ||(text.substring(i, i+3).equals("che")) ||(text.substring(i, i+3).equals("end")) ||(text.substring(i, i+3).equals("gen")) ||(text.substring(i, i+3).equals("sch")) ) cntbitri++; } return cntbitri; } /* count the number of nigramms and trigramms in an english text*/ public static int englishText( String text ) { int cntbitri= 0; /*counter for bi- and trigramms */ /* count bigramms */ for ( int i= 0; i< text.length()-1; i++ ) { if ( (text.substring(i, i+2).equals("th")) ||(text.substring(i, i+2).equals("he")) ||(text.substring(i, i+2).equals("an")) ||(text.substring(i, i+2).equals("in")) ||(text.substring(i, i+2).equals("er")) ||(text.substring(i, i+2).equals("re")) ||(text.substring(i, i+2).equals("on")) ||(text.substring(i, i+2).equals("es")) ||(text.substring(i, i+2).equals("ti")) ||(text.substring(i, i+2).equals("at")) ) cntbitri++; } /* count trigramms */ for (int i= 0; i< text.length()-2; i++) { if ( (text.substring(i, i+3).equals("the")) ||(text.substring(i, i+3).equals("ing")) ||(text.substring(i, i+3).equals("and")) ||(text.substring(i, i+3).equals("ion")) ||(text.substring(i, i+3).equals("tio")) ||(text.substring(i, i+3).equals("ent")) ||(text.substring(i, i+3).equals("ere")) ||(text.substring(i, i+3).equals("her")) ||(text.substring(i, i+3).equals("ate")) ||(text.substring(i, i+3).equals("ver")) ) cntbitri++; } return cntbitri; } public static int findKeyCaesar(String origin) { /* proccedding: * search for most frequent char in encoded text and assume it is * one of the three most frequent letters in german or english * language. * decode text end test if it is decipheable */ origin= takeOutPunctuation( origin ); String text= ""; /* number of occurence of most frequent char: */ int mostFrequentChrValue= 0; int mostFrequentChr= 0; //most frequent char in text char[] en= {'e','t','a',}; //most frequent letters in english char[] ge= {'e','n','i',}; //most frequent letters in german int biTriMax= 0; //maximal value of bi- and trigramms int biTriTemp= 0; int displacement= 0; int key= 0; double kindex= determineKoinzidenzindex(origin); /* System.out.print("Koinzidenzindex: "+ kindex ); if ( kindex < 0.07 ) { System.out.println( " english text" ); } else { System.out.println(" german text" ); } System.out.println( ); */ /* define most frequent char */ int[] chr= frequencyAnalysis(origin); for ( int i= 0; i< chr.length-1; i++) { if ( mostFrequentChrValue< chr[i] ) { mostFrequentChrValue= chr[i]; mostFrequentChr= i; } }//for /*assume most frequent char as (e,t,a)(engl.) or (e,n,i)(germ.) */ for ( int k= 0; k< en.length; k++ ) { /* decide if text german or english */ if ( kindex < 0.07 ) { /*assumed char causes certain displacement */ displacement= (mostFrequentChr+'a') - (int) en[k] ; } else { displacement= (mostFrequentChr+'a') - (int) ge[k] ; } if ( kindex < 0.07) { text= decryptCaesar(origin, displacement); biTriTemp= englishText(text); } else { text= decryptCaesar(origin, displacement); biTriTemp= germanText(text); } /* displacement causing highest biTri value is key */ if ( biTriMax< biTriTemp ) { biTriMax= biTriTemp; key= displacement; } } System.out.println("Schluessel lautet: "+ key ); return key; } public static String encryptCaesar( String text, int key ) { return modifyText(text, key); } public static String decryptCaesar( String text, int key ) { key*= -1; return modifyText(text, key); } public static String modifyText( String text, int key ) { String encrypted= ""; key%= 26; for ( int i= 0; i< text.length(); i++ ) { int currentChar= (int) text.charAt(i); int code= currentChar; /*lower case letters*/ code= filterSigns(currentChar, code, key, 97, 122); /* upper case letters */ code= filterSigns(currentChar, code, key, 65, 90); /* numbers */ code= filterSigns(currentChar, code, key, 48, 57); encrypted+= (char) code; } return encrypted; } /*replaces char only if it is situated in given boundarys*/ public static int filterSigns(int currentChar, int code, int key, int lowerBoundary, int upperBoundary ) { int range= upperBoundary - lowerBoundary + 1; if ( (currentChar >= lowerBoundary) & (currentChar <= upperBoundary) ) { code= currentChar + key; while ( code > upperBoundary ) { code-= range; } while( code < lowerBoundary ) { code+= range; } } return code; } }