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[]) { ...“) |
Jörg F (Diskussion | Beiträge) K (hat „Javakurs2007/Cäsar-Chiffre/Musterlösung“ nach „Javakurs/Übungsaufgaben/Cäsar-Chiffre/Musterlösung“ verschoben: wikistruktur) |
(kein Unterschied)
| |
Version vom 1. August 2010, 11:50 Uhr
/* Decodes texts having been encoded with caesar */
import java.io.*;
public class Caesar {
public static void main(String arg[])
{
int menuCase;
String text= new String();
String textState= "nothing loaded";
String output= new String(); /*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.valueOf(s).intValue();
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.valueOf(readln()).intValue();
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= new String("key is: "+ key);
textState= "decrypted";
break;
}
case 6:
{
System.out.print("key: ");
key= Integer.valueOf(readln()).intValue();
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= new String();
try {
FileReader file = new FileReader (fileName);
BufferedReader buff = new BufferedReader(file);
boolean eof = false;
while ( !eof ) {
String line = buff.readLine();
if ( null == line ) {
eof = true;
} 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= new String();
for ( int i= 0; i<originLowCase.length(); i++ ) {
/* filtering signs 'a' to 'z' using ASCII numbers */
if ( ((int) originLowCase.charAt(i)>= 97)
&& ((int) originLowCase.charAt(i)<= 122) )
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[ ((int) text.charAt(j)) - 97 ]++;
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= new String();
/* 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+97) - (int) en[k] ;
} else {
displacement= (mostFrequentChr+97) - (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= key*(-1);
return ( modifyText(text, key) );
}
public static String modifyText( String text, int key ) {
String encrypted= new String("");
key= key%26;
int code= 0;
int currentChar= 0;
for ( int i= 0; i< text.length(); i++ ) {
currentChar= (int) text.charAt(i);
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;
}
}