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;
}
}