[leicht bis schwer]Krypto-Analyse

CDW

Moderator
Mitarbeiter
#1
Eingereicht von Tarantoga

Beschreibung: Ziel dieser Aufgabe ist es eine Anwendung zu schreiben, die es ermöglicht einen verschlüsselten Text zu analysieren, zu bearbeiten und (im Idealfall;)) zu entschlüsseln. Um das zu können muss die Anwendung über folgende Eigenschaften verfügen:

Einfach
Die Anwendung muss es ermöglichen eine Textdatei mit einem verschlüsselten Text einzulesen.
Um den Text zu analysieren muss die Anwendung folgende Werte ermitteln können:
- die Länge des Textes
- die Häufigkeit der einzelnen Zeichen
Um den Text bearbeiten zu können muss die Anwendung über eine Methode "Suchen & Ersetzen" verfügen, die es ermöglicht bestimmte Zeichen des Textes durch andere Zeichen zu ersetzen (z. B. alle "A" durch "B")
Um die Veränderungen an dem Text zu erhalten, muss die Anwendung natürlich über eine Methode verfügen den bearbeiteten Text in einer neuen Datei zu speichern.

Fortgeschritten
Um die Anwendung etwas mächtiger zu machen, kann man die Methode "Suchen & Ersetzen" differenzierter gestalten, z. B. so das sie es auch ermöglicht nicht nur alle Zeichen eines bestimmten Typs, sondern nur Zeichen an einer bestimmten Stelle zu ersetzen.

Schwierig
Darüber hinaus kann man natürlich bekannte Chiffrier Algorithmen, z. B. den Caesar-Code oder die Vigenére-Chiffre, implementieren und auf den Text anwenden lassen und so versuchen ihn zu entschlüsseln. Beim Caesar-Code könnte der User eine Zahl angeben und die Anwendung verschiebt dann alle Buchstaben des Textes entsprechend, oder einen Bereich von Zahlen (z. B. 1-26) und die Anwendung arbeitet sie nacheinander ab...
Analog dazu kann der User bei der Vigenére-Chiffre ein Wort angeben, das die Anwendung dann als Schlüssel auf den Text anwendet...
 
#2
Hier mal mein erster Entwurf, bzw. Lösungsansatz, wie immer in Java:
Code:
import java.io.*;

public class KryptoAnalyseHabo 
{//class KryptoAnalyseHabo
    private static void vigChiffre(String kryptText)throws IOException
    {//vigChiffre()
        int textLaenge, schluesselLaenge;
        String schluessel, auswahl;
        char[] textVig;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*** Vigenére Chiffre ***");
        System.out.println("\nBitte geben sie ein Wort als Schlüssel ein:");
        schluessel=ein.readLine();
        
        textLaenge=kryptText.length();
        schluesselLaenge=schluessel.length();
        textVig=new char[textLaenge];
        for(int i=0, j=0; i<textLaenge; i++, j++)
        {
            if(j==schluesselLaenge)j=0;
            textVig[i]=(char)(kryptText.charAt(i)-schluessel.charAt(j));
        }
        kryptText="0";
        for(int i=0; i<textLaenge; i++)
        {
            kryptText=kryptText+Character.toString(textVig[i]);
        }
        kryptText=kryptText.substring(1);
        System.out.println("Der Text wurde mit "+schluessel+" als Schluessel dechiffriert:");
        System.out.println(kryptText);
        System.out.println("\n(T)ext bearbeiten, Text (s)peichern, (B)eenden?");
        auswahl=ein.readLine();
        
        if(auswahl.equals("T")||auswahl.equals("t"))
        {
            bearbeiten(kryptText);
        }
        else if(auswahl.equals("S")||auswahl.equals("s"))
        {
            dateiSpeichern(kryptText);
        }
        else if(auswahl.equals("B")||auswahl.equals("b"))
        {
            System.out.println("\nProgramm beendet...");
            System.exit(0);
        }
        else
        {
            System.out.println("Ungültige Eingabe!");
            vigChiffre(kryptText);
        }
    }//vigChiffre()
    private static void caesar(String kryptText)throws IOException
    {//caesar()
        int schluessel, laenge;
        char[] textVerschoben;
        String auswahl;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*** Caesar Code ***");
        System.out.println("\nBitte geben sie eine Zahl als Schlüssel ein:");
        schluessel=Integer.parseInt(ein.readLine());
        
        laenge=kryptText.length();
        textVerschoben=kryptText.toCharArray();
        for(int i=0; i<laenge; i++)
        {
            textVerschoben[i]=(char)(textVerschoben[i]-schluessel);
        }
        kryptText="0";
        for(int i=0; i<laenge; i++)
        {
            kryptText=kryptText+Character.toString(textVerschoben[i]);
        }
        kryptText=kryptText.substring(1);
        System.out.println("Text wurde mit "+schluessel+" als Schlüsselwert dechiffriert:");
        System.out.println(kryptText);
        System.out.println("\n(T)ext bearbeiten, Text (s)peichern, (B)eenden?");
        auswahl=ein.readLine();
        
        if(auswahl.equals("T")||auswahl.equals("t"))
        {
            bearbeiten(kryptText);
        }
        else if(auswahl.equals("S")||auswahl.equals("s"))
        {
            dateiSpeichern(kryptText);
        }
        else if(auswahl.equals("B")||auswahl.equals("b"))
        {
            System.out.println("\nProgramm beendet...");
            System.exit(0);
        }
        else
        {
            System.out.println("Ungültige Eingabe!");
            caesar(kryptText);
        }
    }//caesar()
    private static void dechiffrierenMenue(String kryptText)throws IOException
    {//dechiffrierenMenue()
        String auswahl;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("**** Text dechiffrieren ***");
        System.out.println("\n1 - Caesar Code");
        System.out.println("2 - Vigenére Chiffre");
        System.out.println("Welchen Algorithmus wollen sie auf den Text anwenden?");
        auswahl=ein.readLine();
        
        if(auswahl.equals("1"))
        {
            caesar(kryptText);
        }
        else if(auswahl.equals("2"))
        {
            vigChiffre(kryptText);
        }
        else
        {
            System.out.println("Ungültige Eingabe!");
            dechiffrierenMenue(kryptText);
        }
    }//dechiffrierenMenue()
    private static void bearbeiten(String kryptText)throws IOException
    {//bearbeiten()
        String auswahl, datei;
        char muster, neu;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        System.out.println("*** Text bearbeiten ***");
        System.out.println(kryptText);
        System.out.println("\n(S)uchen & ersetzen, (D)echiffrieren, (T)ext speichern, (B)eenden");
        auswahl=ein.readLine();
        
        if(auswahl.equals("S")||auswahl.equals("s"))
        {
            System.out.println("Welches Zeichen möchten sie ersetzen?");
            muster=ein.readLine().charAt(0);
            System.out.println("Durch welches Zeichen wollen sie "+muster+" ersetzen?");
            neu=ein.readLine().charAt(0);
            kryptText=kryptText.replace(muster, neu);
            //System.out.println(kryptText);
            bearbeiten(kryptText);
        }
        else if(auswahl.equals("D")||auswahl.equals("d"))
        {
            dechiffrierenMenue(kryptText);
        }
        else if(auswahl.equals("T")||auswahl.equals("t"))
        {
            dateiSpeichern(kryptText);
        }
        else if(auswahl.equals("B")||auswahl.equals("b"))
        {
            System.out.println("\nProgramm beendet...");
            System.exit(0);
        }
        else
        {
            System.out.println("\nUngültige Eingabe!");
            bearbeiten(kryptText);
        }
    }//bearbeiten()
    private static void analysiere(String kryptText)throws IOException
    {//analysiere()
        int zeichenGesamt;
        char[]kryptChar;
        int[]counter;
        boolean[]doppelt;
        String auswahl;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        zeichenGesamt=kryptText.length();
        counter=new int[zeichenGesamt];
        doppelt=new boolean[zeichenGesamt];
        kryptChar=kryptText.toCharArray();
        
        for(int i=0; i<zeichenGesamt; i++)
        {
            for(int j=0; j<zeichenGesamt; j++)
            {
                if(kryptChar[i]==kryptChar[j])
                {
                    counter[i]++;
                }
            }
        }
        System.out.println("Text:\n"+kryptText);
        System.out.println("Der Text besteht aus "+zeichenGesamt+" Zeichen");
        System.out.println("Häufigkeitsanalyse:");
        
        for(int i=0; i<zeichenGesamt; i++)
        {
            for(int j=i+1; j<zeichenGesamt; j++)
            {
                if(kryptChar[i]==kryptChar[j])
                {
                    doppelt[j]=true;
                }
                if(doppelt[i]!=true)
                {
                    System.out.print(">"+kryptChar[i]+"< Anzahl: "+counter[i]+" ");
                    for(int k=0; k<counter[i]; k++)
                    {
                        System.out.print("*");
                    }
                    System.out.print("\n");
                    doppelt[i]=true;
                }
            }
        }
        
        System.out.println("(T)ext bearbeiten, Text (s)peichern oder (B)eenden?");
        System.out.println("Ihre Wahl?");
        auswahl=ein.readLine();
        
        if(auswahl.equals("T")||auswahl.equals("t"))
        {
            bearbeiten(kryptText);
        }
        else if(auswahl.equals("S")||auswahl.equals("s"))
        {
            dateiSpeichern(kryptText);
        }
        else if(auswahl.equals("B")||auswahl.equals("b"))
        {
            System.out.println("Programm beendet...");
            System.exit(0);
        }
        else
        {
            System.out.println("\nUngültige Eingabe!");
            analysiere(kryptText);
        }
    }//analysiere()
    private static void dateiSpeichern(String kryptText)throws IOException
    {
        int textLaenge=kryptText.length();
        char[] dateiInhalt=new char[textLaenge+1];
        String datei;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*** Text speichern ***");
        System.out.println("\nUnter welchem Namen wollen sie den Text speichern?");
        datei=ein.readLine();
        BufferedWriter dateiSchreiber=new BufferedWriter(new FileWriter(datei+".txt"));
        
        for(int i=0; i<textLaenge; i++)
        {
            dateiInhalt[i]=kryptText.charAt(i);
            dateiSchreiber.write(dateiInhalt[i]);
        }
        dateiSchreiber.close();
        menue();
    }
    private static void dateiLaden()throws IOException
    {//dateiLaden()
        String dateiInhalt="0", datei, zeile, kryptText;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*** Datei laden ***");
        System.out.println("\nWelche Datei soll geladen werden?");
        datei=ein.readLine();
        
        try
        {
            BufferedReader dateiLeser=new BufferedReader(new FileReader(datei+".txt"));
            
            while((zeile=dateiLeser.readLine())!=null)
            {
                dateiInhalt=dateiInhalt+zeile+"\n";
            }
            kryptText=dateiInhalt.substring(1, dateiInhalt.length()-1);
            analysiere(kryptText);
        }
        catch(java.io.FileNotFoundException e)
        {
            System.out.println("Datei >"+datei+"< konnte nicht gefunden werden...");
            System.out.println("Bitte überprüfen sie die Schreibweise und stellen Sie");
            System.out.println("sicher, dass sich die Datei im Ordner >KryptoAnalyseHabo< befindet!\n");
            menue();
        }
    }//dateiLaden()
    private static void menue()throws IOException
    {//menue()
        String auswahl, datei;
        BufferedReader ein=new BufferedReader(new InputStreamReader(System.in));
        
        System.out.println("*** KryptoAnalyzer (Habo) ***");
        System.out.println("1 - Datei laden");
        System.out.println("2 - Programm beenden");
        System.out.println("Ihre Wahl?");
        auswahl=ein.readLine();
        
        if(auswahl.equals("1"))
        {
            dateiLaden();
        }
        else if(auswahl.equals("2"))
        {
            System.out.println("Programm beendet...");
            System.exit(0);
        }
        else
        {
            System.out.println("Ungültige Eingabe!");
            menue();
        }
    }//menue()
    public static void main(String[]args)throws IOException
    {//main()
        menue();
    }//main()
}//class KryptoAnalyseHabo

Dieser Entwurf unterstützt zwar bereits den Caesar Code und die Vigenére Chiffre, dabei habe ich aber sozusagen geschummelt, denn der Algorithmus arbeitet nicht mit Buchstaben, sondern mit chars - das hat zwar den Vorteil das auch Sonderzeichen "verschlüsselt/entschlüsselt" werden können, führt aber auch teilweise zu seltsam anmutenden Ausgaben...:rolleyes:
Darüber hinaus muss der User bis jetzt beim Caesar Code den Schlüssel für jeden Versuch einzeln eingeben, was bei vielen Versuchen recht unkomfortabel ist. Auch das Suchen&Ersetzen ist noch ganz einfach gehalten und ermöglicht bislang nur alle Zeichen eines Typs zu ersetzen.
Ausserdem gibt es sicher noch massig andere Dinge die man einbauen, bzw. verbessern könnte - doch da gleich der BVB spielt, muss das alles warten...:p
 

v2.0

Stammuser
#3
Java Lösung

hi freunde,
meine lösung beinhaltet folgende fähigkeiten:
Code:
MENÜ:
1 - Einzelnen Buchstaben manuell austauschen
2 - Alle Buchstaben eines Typs manuell austauschen
3 - Alle Buchstaben um Faktor n verschieben (Caesar)
4 - Schlüsselwort eingeben (Vigenere)
5 - Details anzeigen
6 - Text anzeigen
7 - Ursprünglichen Text wiederherstellen
8 - Bearbeiteten Text in Datei speichern
9 - Alle Caesarkeys von 1-26 einmal durchgehen und Texte anzeigen
0 - Programm beenden
wie immer ist die lösung nicht perfekt, z.B. stürtzt das programm ab wenn man einfach nur enter eingibt, aber ansonsten funktioniert es ganz gut :)


Code:
import java.io.*;
import java.nio.file.*;

public class KriptoAnalyse {
	final public static String alphabet = "abcdefghijklmnopqrstuvwxyz";
	public static Path filePath;
	public static Path destFile;
	public static StringBuffer text = new StringBuffer();
	public static StringBuffer originalText = new StringBuffer();
	public static int haeufigkeit[] = new int[alphabet.length()]; 						
	
	public static boolean setPath(String datei) {
		String current = System.getProperty("user.dir");
		filePath = Paths.get(current, datei);
		if (Files.exists(filePath)) {
			return true;
		} else {
			return false;
		}
	}
	
	public static Path getPath() {
		return filePath;
	}
	
	public static void setDestFile(String datei) {
		String current = System.getProperty("user.dir");
		destFile = Paths.get(System.getProperty(current, datei));
		
	}
	
	public static void textIn() throws IOException {
		FileReader freader = new FileReader(filePath.toString());
	    BufferedReader breader = new BufferedReader(freader);
	    while (true) {
	    	String line = breader.readLine();
	    	if (line == null) {
	    		break;
	    	} else {
	    		line = line.toLowerCase();
	    		text.append(line);
	    		text.append('\n');
	    	}
	    }
	    breader.close();
	    freader.close();
	}
	
	public static void showText() {
		System.out.print(text.toString());
	}
	
	public static void setOriginalText() {
		originalText.append(text.toString());
	}
	
	public static void getOriginalText() {
		text = originalText;
	}
	
	public static void textOut() throws IOException {
		FileWriter fwriter = new FileWriter(destFile.toString());
	    BufferedWriter bwriter = new BufferedWriter(fwriter);
	    char cin;
	    for (int i=0; i<text.length(); i++) {
	    	cin = text.charAt(i);
	    	if (cin == '\n') {
	    		bwriter.newLine();
	    	} else {
	    		bwriter.write(cin);
	    	}	    	
	    }
	    bwriter.close();
	    fwriter.close();
	}
	
	public static void showTextStats() {
		for (int i=0; i<haeufigkeit.length; i++) {
			haeufigkeit[i] = 0;
		}
		for (int i=0; i<text.length(); i++) {
			char cin = text.charAt(i);
			for (int j=0; j<alphabet.length(); j++) {
				if (cin == alphabet.charAt(j)) {
					haeufigkeit[j]++;; 
				}
			}
		}
		System.out.println("\nHäufigkeit der Buchstaben:");
		for (int i=0; i<alphabet.length(); i++) {
			System.out.println("Buchstabe: " + alphabet.charAt(i) + " = " + haeufigkeit[i]);
		}
		System.out.println("\nLänge des Textes:" + text.length());
	}
	
	public static void changeLetter(char alt, char neu) {
		for (int i=0; i<text.length(); i++) {
			if (alt == text.charAt(i)) {
				text.setCharAt(i, neu);
			}
		}
	}
	
	public static void caesar(int key) {
		StringBuffer codedText = new StringBuffer();
		for (int i=0; i<text.length(); i++) {
			boolean isAlpha = false;
			char c = text.charAt(i);
			for (int j=0; j<alphabet.length(); j++) {
				if(c == alphabet.charAt(j)) {
					isAlpha = true;
				}
			}
			if (isAlpha == true) {
				int pos = alphabet.indexOf(c);
				for (int j=0; j<key; j++) {
					if((pos) == (alphabet.length()-1)) {
						pos = 0;
					} else {
						pos++;
					}
				}
				codedText.append(alphabet.charAt(pos));
			} else if(!Character.isLetter(c)) {
				codedText.append(c);
			}
		}
		text = codedText;
	}
	
	public static void vigenere(String key) {
		StringBuffer decodedText = new StringBuffer();
		int schluessel[] = new int[key.length()];
		int zaehler = 0;
		for (int i=0; i<key.length(); i++) {
			schluessel[i] = alphabet.indexOf(key.charAt(i));
		}
		for (int i=0; i<text.length(); i++) {
			if (zaehler == schluessel.length) {
				zaehler = 0;
			}
			boolean isAlpha = false;
			char c = text.charAt(i);
			for (int j=0; j<alphabet.length(); j++) {
				if(c == alphabet.charAt(j)) {
					isAlpha = true;
				}
			}
			if (isAlpha == true) {
				int pos = alphabet.indexOf(c);
				for (int j=0; j<schluessel[zaehler]; j++) {
					if((pos) == 0) {
						pos = (alphabet.length()-1);
					} else {
						pos--;
					}
				}
				decodedText.append(alphabet.charAt(pos));
			} else if(!Character.isLetter(c)) {
				decodedText.append(c);
			}
			zaehler++;
		}
		text = decodedText;
	}
	
	public static void menue() throws IOException {
		System.out.println("Kripto Analyse");
		System.out.println("Geben Sie die zu öffnende Textdatei an");
		System.out.println("Hinweis: Die Datei muss sich im selben Ordner befinden wie das auszuführende Programm / also ich :=)");
		System.out.print("Eingabe: ");
		String datei;
		boolean exist = false;
		while (exist == false) {
			datei = new java.util.Scanner(System.in).nextLine();
			if (setPath(datei)==true) {
				setPath(datei);
				exist = true;
			} else {
				System.out.println("Datei (" + datei + ") nicht gefunden");
				System.out.print("Bitte versuchen Sie es erneut: ");
			}

		}
		System.out.println("Datei geöffnet: (" + getPath().toString() + ")");
		textIn();
		setOriginalText();
		boolean exit = false;
		while (!exit) {
			System.out.println("\nMENÜ:");
			System.out.println("1 - Einzelnen Buchstaben manuell austauschen");				
			System.out.println("2 - Alle Buchstaben eines Typs manuell austauschen");		
			System.out.println("3 - Alle Buchstaben um Faktor n verschieben (Caesar)");		
			System.out.println("4 - Schlüsselwort eingeben (Vigenere)");
			System.out.println("5 - Details anzeigen");										
			System.out.println("6 - Text anzeigen");										
			System.out.println("7 - Ursprünglichen Text wiederherstellen");					
			System.out.println("8 - Bearbeiteten Text in Datei speichern");		
			System.out.println("9 - Alle Caesarkeys von 1-26 einmal durchgehen und Texte anzeigen");	
			System.out.println("0 - Programm beenden\n");									
			System.out.print("Wählen Sie eine Operation: ");
			char cin = new java.util.Scanner(System.in).nextLine().charAt(0);
			if (cin == '1') {
				System.out.println("Geben Sie die Position des Buchstabens an, den Sie austauschen möchten");
				System.out.println("Möglichkeiten: 1 - " + text.length() + " (als Ganzzahl)");
				System.out.print("Eingabe: ");
				int pos = new java.util.Scanner(System.in).nextInt();
				pos--;
				System.out.print("Geben Sie nun den Buchstaben ein, den Sie statt (" + text.charAt(pos) + ") einsetzen möchten: ");
				char ersetzt = new java.util.Scanner(System.in).nextLine().charAt(0);
				Character.toLowerCase(ersetzt);
				text.setCharAt(pos, ersetzt);
				System.out.println("Operation erfolgreich");
				
			} else if (cin == '2') {
				System.out.print("Geben Sie den Buchstaben an, den Sie austauschen möchten: ");
				char buchstabe = new java.util.Scanner(System.in).nextLine().charAt(0);
				Character.toLowerCase(buchstabe);
				boolean possible = false;
				for (int i=0; i<alphabet.length(); i++) {
					if (buchstabe == alphabet.charAt(i)) {
						possible = true;
					}
				}
				if (possible == true) {
					System.out.println("Geben Sie den Buchstaben an, den Sie mit (" + buchstabe + ") austauschen möchten");
					System.out.print("Eingabe: ");
					char neuerb = new java.util.Scanner(System.in).nextLine().charAt(0);
					Character.toLowerCase(neuerb);
					possible = false;
					for (int i=0; i<alphabet.length(); i++) {
						if (neuerb == alphabet.charAt(i)) {
							possible = true;
						}
					}
					if (possible == true) {
						changeLetter(buchstabe, neuerb);
						System.out.println("Operation erfolgreich");
					}
				} else {
					System.out.println("Ungültige Eingabe");
					System.out.println("Bitte versuchen Sie es erneut\n");
				}
			} else if (cin == '3') {
				System.out.println("Geben Sie nun den Caesar-Key an (Ganzzahl zwischen 1 und 26)");
				System.out.println("Eingabe: ");
				int keyin = new java.util.Scanner(System.in).nextInt();
				if (keyin < 27 && keyin > 1) {
					caesar(keyin);
				} else {
					System.out.println("Ungültige Eingabe");
				}
			} else if (cin == '4') {
				System.out.println("Geben Sie nun den Vigenere-Key an (Zeichenkette z.B.: AKEY)");
				System.out.println("Hinweis: Die Methode arbeitet rückwärts, da sie fürs encoden gedacht ist");
				System.out.println("Eingabe: ");
				String keystr = new java.util.Scanner(System.in).nextLine();
				keystr = keystr.toLowerCase();
				boolean checkit = true;
				for (int i=0; i<keystr.length(); i++) {
					boolean isfalse = true;
					for (int j=0; j<alphabet.length(); j++) {
						if (keystr.charAt(i) == alphabet.charAt(j)) {
							isfalse = false;
							System.out.println("foundsame");
						}
					}
					if (isfalse == true) {
						checkit = false;
					}
				}
				if (checkit == true) {
					vigenere(keystr);
				} else {
					System.out.println("Ungültige Eingabe");
					System.out.println("Hinweis: Es sind nur lateinische Buchstaben als Schlüssel erlaubt");
				}
			} else if (cin == '5') {
				showTextStats();
			} else if (cin == '6') {
				System.out.println("\nText:");
				showText();
			} else if (cin == '7') {
				getOriginalText();
			} else if (cin == '8') {
				System.out.println("Datei speichern -> Geben Sie einen Dateinamen ein");
				System.out.println("Hinweis: Die Datei wird im selben Ordner gespeichert wie das auszuführende Programm / also ich :=)");
				System.out.print("Eingabe: ");
				String newfile = new java.util.Scanner(System.in).nextLine();
				setDestFile(newfile);
				textOut();
				System.out.println("Textdatei erfolgreich gespeichert");
			} else if (cin == '9') {
				for (int i=1; i<=26; i++) {
					System.out.println("KEY: " + i);
					System.out.println("Text:");
					caesar(i);
					showText();
					System.out.println();
					getOriginalText();
				}	
			} else if (cin == '0') {
				exit = true;
			} else {
				System.out.println("Ungültige Eingabe");
				System.out.println("Bitte versuchen Sie es erneut\n");
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
		menue();
	}
}
 

M@gic

Stammuser
#4
Vorschlag Erweiterung

Wie wäre es jetzt noch mit einem brute force - rijndael ?
Falls jemand lange Weile hat :)
Das größte Problem dabei wird allerdings sein, rein programmatisch zu entscheiden, wann das Ziel (die Entschlüsselung) erreicht ist.

Edit: Hoffentlich lebt dann noch jemand von uns, der das Ergebnis bewerten kann (bei 256 bit key).
 
Zuletzt bearbeitet:
#5
Meine Lösung

Da meine Lösung sehr umfangreich ist, habe ich es in mehrere Dateien gesplittet (Module). Umgesetz habe ich das ganze mal in Perl. Das Programm wird über Kommandozeilenparameter gesteuert. Und kann aus ihrer Anzahl erfassen was zu tun ist.

1. Parameter: Dateiname (am besten im gleichen verzeichnis)
2. Parameter: Suchbegriff
3. Parameter: Ersetzungsstring


Hier das Hauptprogramm
Code:
#! /usr/bin/perl 


# #####################################
# test.pl
# --------------------------------------
# Kommandozeilenargumente:
# 1. Argument muss der Pfad sein
# 2. Argument muss/kann Suchbegriff sein.
# 3. Argument muss/kann Ersetzungsstring sein.
# --------------------------------------
# Anmerkung: Am besten in dem Verzeichnis aufrufen
# in dem sich auch die betreffende Datei aufhält. 
# ############################################

use modul; # Hier stehen die Funktionen 
        # anteil und suchen drin. 

use suchenErsetzen; # Hier ist die Such & Ersetz 
            # Funktionalität enthalten.       


my $suchStatus = 0; # Soll überhaupt gesucht werden?
my $ersetzStatus =0; # Soll irgendwas ersetzt werden?
my $len = @ARGV; # Anzahl der Kommandozeilenparameter
my $pfad = shift @ARGV; # 1. Kommandozeileargument ist der Pfad. 
my $such = shift @ARGV; # Suchmuster laden aus Kommadozeilenparameter.
my $ersetzung = shift @ARGV; # Ersetzungsstring
if ( $len == 2) {
    $suchStatus =1;
}

if ($len == 3) {
    $ersetzStatus =1;
}
my $laenge =0;    # spätere Länge des Textes. 
my $zeile = ""; # Jeweilige Zeile aus Datei. 
my $string =""; # In diesen String wir der ganze Inhalt 
        # der Textdatei stehen!
my $count = 0; # Zählt die Zeilen in der Datei.
open (my $fh1, "<", $pfad) or die "Auf Datei konnte nicht zugegriffen werden!"; 
# Öffnen der Datei. Bereitstellung eines Dateihandle.

$zeile = <$fh1>; # 1. Zeile wird gelesen.
while ($zeile) { # Solange nicht EOF soll Schleife weiterlaufen. 
    $count++; # Nächste Zeile zählen!
    chomp $zeile; # Entfernung der newline /n Zeichen. 
    suchen ($zeile,$suchStatus,$such,$count); # Sucht nach dem Begriff und gibt
                          # die Treffer aus!
    $laenge += length($zeile);    # Erfassung der Anzahl an Zeichen. 
    $string = $string.$zeile;    # Bildung des Gesamtinhaltes in $string
    $zeile = <$fh1>;
    
}





#Ausgabe Teil
print "Der Text hat eine Laenge von $laenge Zeichen!\n";
anteil $string; # Berechnung der Anteile und Ausagabe!
suchenErsetzen ($pfad,$such,$ersetzung,$ersetzStatus);
# suchenErsetzen übernimmt den kompletten Ersetzungsvorgang
# und Schreibvorgang in neue Datei. Anschließende Ausgabe
# einer Meldung. 

close($fh1);

exit(0);

# Definitionsteil
In diesem Modul befinden sich die Prozeduren anteil, die dafür da ist die Häufigkeiten der einzelnen Zeichen in Prozent zu ermitteln. und suchen, die den Auftrag hat auf der Konsole die Suchergebnisse für einen bestimmten Suchbegriff auszugeben. Also in welcher Zeile und Spalte der Textdatei der Suchbegriff gefunden wurde.
Code:
# ####################################
# anteil
# --------------------------------------------
# argumente: string (Gesamtinhalt der Datei)
# Gibt auf der Konsole die Anteile der 
# einzelnen Zeichen aus. 
# #######################################

sub anteil { # Zur bestimmung der Häufigkeit.
    my $arg = shift @_; # Übergabe eines Strings.
    chomp $arg; # Entfernen der newline Zeichen \n
    my @liste = split (//,$arg); # Zerlegung in einzelne Zeichen. 
    my $laenge = @liste; # Länge des Array!    
    my $count = 1; # Das festgehaltene Zeichen muss gleich gezählt werden. 
    my $anteil =0.0;
    my @sammlung = (); # Wir sammeln die Zeichen die gezählt wurden. 
    my $status = 0; # Status zum prüfen ob Zeichen schon gezählt wurde. 
    my $gesamt =0;
    
    for ($i=0; $i < $laenge; $i += 1) {
# Die foreach dient zum erfassen, welche Zeichen schon gezählt wurden!        
        foreach (@sammlung) {
            if (@liste[$i] eq $_ ) { 
                $status = 1; 
                last;
}
            else { 
                $status = 0; 
                
}
            #print "In foreach (anteil) status: $status zeichen: @liste[$i] \n";
}
        
        if ( !$status) {
        $zeichen = @liste[$i]; 
# Wir halten immer das zu zählende Zeichen fest! Deshalb count = 1 !
        push (@sammlung,$zeichen);
        
        #print "In anteil zeichen: $zeichen sammlung: @sammlung \n";
        for ($j = $i+1; $j < $laenge; $j += 1) {
            if ($zeichen eq @liste[$j]) {
                $count++;
}
}

        
        $anteil = ($count/$laenge) * 100; # Prozentsatz berechnen. 
        $gesamt += $anteil;
        #print "In anteil count: $count zeichen: $zeichen\n";
        #print "In anteil : ", (($count+0.0)/$laenge) , "\n"; #Fehlersuchinfo
        print "Das Zeichen $zeichen kommt mit $anteil % Haeufigkeit vor!\n";
        $count =1; # Zähler wieder auf Null setzen.
        #print "In anteil zeichen : $zeichen und sammlung : @sammlung \n";
        
} 
}
    
}

# ##########################################################
# Name: suchen
# -------------------------------------------------------------
# argumente: string , status, suchbegriff, zeilennummer
# Gibt auf Konsole die gefunden Treffer (mit Zeilennummern) aus.
# ########################################################
sub suchen {
    my $string = shift; # Einzelne Zeile
    my $status = shift; # Status : Soll überhaupt gesucht werden?
    my $suchbegriff = shift; # Nach was soll gesucht werden?
    my $zeilennummer = shift; # Aktuelle Zeilennummer
    my @zeilenmerker = (); # Zum Zwischenspeichern der einzelnen Zeilen
                # in denen etwas gefunden wurde.
    # ACHTUNG: @zeilenmerker ist überflüssig! 
    # Da sowieso immer nur eine Zeile geprüft wird und
    # deren Zeilennummer ist schon bekannt. 
    my @spaltenmerker =(); # Hier speichern wir die Spalte zwischen.  
    my @character =(); # Enthält die einzelnen Zeichen des übergeben
               # Strings. 
    my $lenCharacter =0; # Länge des obigen Array.
    my $spalte =0; # Spalte in der sich der Treffer befindet. 
    if ($status) {
        if ($string =~ s/$suchbegriff/@!/gi) { # Wir setzen eine
                            # Marke @!
             push(@zeilenmerker,$zeilennummer);     
}
    @character = split(//,$string);
    $lenCharacter = @character;
    for (my $i=0;$i < $lenCharacter; $i++) { # Hier lokalisieren wir die Marke @!
        if ((@character[$i] eq "@") && (@character[$i+1] eq "!")) {
            push(@spaltenmerker,$i);
            
}
}
    
    
    if (@zeilenmerker) { # Wenn etwas gefunden wurde wird der Rumpf der 
                     # If-Verzweigung aktiv. Und die einzelnen
                 # Zeilennummern in denen es Treffer gab 
                 # werden ausgegeben. 
     my $lenzeilen = @zeilenmerker; 
    my $lenspalten = @spaltenmerker;
    for (my $n =0; $n < $lenspalten; $n++) {
        @spaltenmerker[$n]++;
    print "[ $suchbegriff ] Zeile: $zeilennummer Spalte: @spaltenmerker[$n] \n";



}


}
        
}
}



1;
Und in dem letzten Modul befindet sich die Prozedur suchenErsetzen , diese hat den Auftrag einen Suchbegriff durch einen Ersetzungsstring zu ersetzen und das ganze in eine neue Datei zu schreiben.
Code:
# #####################################################
# suchenErsetzen
# --------------------------------------
# Argumente: Dateipfad , suchbegriff , ersetzungsstring, Status
# Generiert eine Datei die, die Ersetzungen 
# enthält.
# #######################################################

sub suchenErsetzen {
    my $pfad = shift;
    my $suchbegriff = shift;
    my $ersetzung = shift;
    my $status = shift;
    my $zeile = ""; # Hier die einzelnen Zeilen der Eingabedatei
    if ($status) {
      open (my $eingang, "<",$pfad) or die "Fehler beim lesen Eingang"; # Eingangsdatei
      open (my $ausgang, ">","ers_".$pfad) or die "Fehler beim lesen Aus"; # Ausgangsdatei 
        $zeile = <$eingang>;
        while ($zeile) {
            if (!($zeile =~ s/$suchbegriff/$ersetzung/gi)) { 
                # Wenn suchbegriff nicht auffindbar dann Meldung
                # ausgeben.
                print "[ $suchbegriff ] nicht auffindbar!\n";
}
            print $ausgang $zeile;
            $zeile = <$eingang>; # Neue Zeile aus Datei holen. 
}
    close ($ausgang);
    close ($eingang);
    print "Schreibvorgang beendet!\n";
} # Ende If(status)

    

}

1;
Weiterhin ermittelt das Programm auch die Länge (Anzahl der Zeichen) der Textdatei.

Mit freundlichen Grüßen

Christian
 
Oben