Idee: Ein Text wird verschleiert, indem jeder Buchstabe $k$ Positionen weiter im Alphabet geschoben wird (wobei nach 'Z' wieder 'A' folgt).
Es gibt also nur 25 mögliche Schlüssel, was die Entschlüsselung auch von Hand trivial macht.
Im Pseudocode verwenden wir Variablen. Diese können im Laufe des Programms Ihre Werte wechseln (was in der Mathematik unüblich ist). Z.B. wird der Buchstabe $b$ u.U. mehrmals geändert, bevor er dem Resultat $r$ hinzugefügt wird (das sich auch in jeder Wiederholung ändert).
Was kommt als Resultat mit dem Input $t=$“Hey You!” und $k=3$ heraus?
Pseudocode ist eine Beschreibung eines Algorithmus (Rechenvorschrift, z.B. ein Computerprogramm), die von Menschen gelesen werden soll. Ein Pseudocode richtet sich an ein bestimmtes Publikum und kann mehr oder weniger viele Elemente aus einer bestimmten Programmiersprache enthalten.
Für das Zielpublikum müssen alle Anweisungen unmissverständlich klar sein und alle müssen für den gleichen Input das gleiche Resultat produzieren (von Flüchtigkeitsfehlern mal absgesehen).
Zwingende Elemente sind:
Typische Elemente sind:
Der Text und der Schlüssel werden direkt im Programm festgelegt. Die Ausgabe erfolgt auf der Konsole.
ord
liefert den ASCII-Code (eine Zahl) für ein gegebenes Symbol (Buchstabe), d.h. die dem Symbol zuordnete Nummer.ord('A')
die Zahl 65, oder ord(' ')
Die Zahl 32 (Code vom Leerschlag).chr
liefert das Symbol (als Text) für den gegebenen ASCII-Code (Zahl).chr(65)
den Text 'A'
, chr(97)
den Text 'a'
.3
und '3'
nicht das Gleiche. 3
steht für die Zahl 3 (womit auch gerechnet werden kann) und '3'
steht für das Symbol (mit ASCII Code 51).text = "Hey You!" key = 3 result = "" for symbol in text: if symbol>='A' and symbol<='Z': symbol = chr(ord(symbol)+ord('a')-ord('A')) if symbol>='a' and symbol<='z': nummer = ord(symbol)+key if nummer<ord('a'): nummer = nummer+26 if nummer>ord('z'): nummer = nummer-26 symbol = chr(nummer) result = result + symbol print(result)
Gehen Sie in ein geeignetes Verzeichnis (eventuell neu anlegen) und öffnen Sie eine neue Datei in VSCode:
mkdir caesar cd caesar code caesar.py
Wenn der Code dann kopiert und gespeichert ist, kann er wie folgt ausgeführt werden:
python caesar.py
Es werden direkt im Programmcode zwei Dateien und der Schlüssel festgelegt:
input_datei = "input.txt" key = 3 output_datei = "output.txt" # Datei öffnen und einlesen (r für read) with open(input_datei, "r") as f: text = f.read() print(text) result = "" for symbol in text: if symbol>='A' and symbol<='Z': symbol = chr(ord(symbol)+ord('a')-ord('A')) if symbol>='a' and symbol<='z': nummer = ord(symbol)+key if nummer<ord('a'): nummer = nummer+26 if nummer>ord('z'): nummer = nummer-26 symbol = chr(nummer) result = result + symbol print(result) # Datei überschreiben und ausgeben (w für write) with open(output_datei,"w") as f: f.write(result)
Legen Sie eine Datei input.txt
mit einem Text drin an. Verschleiern Sie diese. Kopieren Sie dann wie folgt die Datei output.txt
auf die Datei input.txt
:
cp input.txt output.txt
Passen Sie dann im Programm den Schlüssel entsprechend an und überprüfen Sie, ob auch der Originaltext wieder erzeugt wird (bis auf Gross-/Kleinschreibung).
Diese Variante liest entweder direkt von der Konsole oder von einer Datei, und schreibt ebenfalls direkt auf die Konsole oder in eine Datei.
Der Schlüssel wird ebenfalls auf der Kommandozeile angegeben.
Starten Sie das Programm mit
python caesar3.py -h
um die Hilfe angezeigt zu bekommen.
import argparse import sys import os # Kommandozeilenoptionen festlegen parser = argparse.ArgumentParser(description='Einfache Caesar-Verschleierung') parser.add_argument('-k', '--key', nargs=1, type=int, help="Schlüssel, zwischen -25 und 25", required=True) parser.add_argument('-i', '--infile', type=str, help="Optional: Datei, wovon gelesen werden soll.") parser.add_argument('-o', '--outfile', type=str, help="Optional: Datei, wohin das Resultat geschrieben werden soll.") parser.add_argument('-f', '--force', action="store_true", help="Output-Datei wird überschrieben, falls sie schon existiert"); # Auswerten args = parser.parse_args() # Schlüssel bestimmen key = args.key[0] if (key<-25 or key>25): sys.stderr.write("Der Schlüssel muss zwischen -25 und 25 liegen\n") exit(-1) # Programm mit Fehlerstatus beenden # Text von Datei oder Standardinput lesen text = "" # Input Datei gegeben? if args.infile: # Datei öffnen und einlesen (r für read) if not os.path.exists(args.infile): sys.stderr.write(f"Input Datei {args.infile} nicht gefunden\n") exit(-1) with open(args.infile, "r") as f: text = f.read() else: # sonst vom Standard-Input lesen text = sys.stdin.read() # Verschleierung result = "" for symbol in text: if symbol>='A' and symbol<='Z': symbol = chr(ord(symbol)+ord('a')-ord('A')) if symbol>='a' and symbol<='z': nummer = ord(symbol)+key if nummer<ord('a'): nummer = nummer+26 if nummer>ord('z'): nummer = nummer-26 symbol = chr(nummer) result = result + symbol # Resultat in Datei oder Standard Output ausgeben if args.outfile: if (os.path.exists(args.outfile)) and (not args.force): sys.stderr.write(f"Die Datei {args.outfile} existiert bereits. Benutzen Sie -f um diese zu überschreiben\n") exit(-1) # Datei überschreiben und ausgeben (w für write) with open(args.outfile, "w") as f: f.write(result) else: # Sonst ausgabe auf Standard Ouput sys.stdout.write(result) # Fast das gleiche wie print(result), ausser dass print immer einen Zeilenumbruch hinzufügt.
Probieren Sie das Programm auf alle Varianten aus (mit/ohne Input-Datei, mit/ohne Output-Datei).
Verschleiern Sie einen kleinen Text mit einem «geheimen» Schlüssel. Tauschen Sie die Text-Dateien (kein Word bitte!) mit Ihrem Banknachbar aus. Entschleiern Sie dann den Text. Können Sie den richtigen Schlüssel auf Anhieb erraten?
Knacken Sie folgenden Text:
bliqvkvokvfyevrsjkrveuvjzeujtynzvizxviqlviirkve
Anspruchsvolle Aufgabe
Die hier programmierte Verschleierungsmethode ist insofern unschön, dass beim Entschlüsseln nicht unbedingt wieder der Originaltext herauskommt, weil Grossbuchstaben zu Kleinbuchstaben konvertiert werden.
Erweitern Sie das Programm so, dass Grossbuchstaben auch in Grossbuchstaben verschleiert werden. Dazu müssen Sie die 2 Fälle gross/klein separat verschleiern. Ersetzen Sie dazu den if
-Block, wo Gross- zu Kleinbuchstaben ersetzt werden mit einem entsprechenden Block, der die Verschleierung von Grossbuchstaben vornimmt (analog zur Verschleierung der Kleinbuchstaben).
Sehr anspruchsvolle Aufgabe
Entwerfen Sie eine Methode (erst mal als Pseudocode), das beliebige deutsche verschleierte Texte automatisch entschlüsselt (bzw. den wahrscheinlichsten Schlüssel findet).
Laden Sie beide Dateien herunter: decryptor.py bigramme.py
Verwenden Sie das Programm wie folgt:
python decryptor.py secret.txt
Wobei der zu entschlüsselnde Text in der Datei secret.txt
gespeichert ist (kann natürlich auch anders heissen).