Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| lehrkraefte:blc:informatik:glf22:caesar [2022/11/04 07:17] – [Flexiblere Variante mit Kommandozeilenargumenten] Ivo Blöchliger | lehrkraefte:blc:informatik:glf22:caesar [2022/11/04 08:10] (current) – [Entschlüsseln] Ivo Blöchliger | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Cäsar «Verschlüsselung» (Verschleierung) ====== | ||
| + | Idee: Ein Text wird verschleiert, | ||
| + | Es gibt also nur 25 mögliche Schlüssel, was die Entschlüsselung auch von Hand trivial macht. | ||
| + | |||
| + | ===== Pseudocode für die Verschleierung ===== | ||
| + | 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). | ||
| + | |||
| + | * **Input**: Text $t$, Schlüssel $k$ (Ganzzahl zwischen $-25$ und $25$). | ||
| + | * **Output**: Verschleierter Text | ||
| + | * $r=$"" | ||
| + | * Für jeden Buchstaben $b$ im Text $t$: | ||
| + | * Wenn $b$ ein Grossbuchstabe ist, sei $b$ der entsprechende Kleinbuchstabe | ||
| + | * Wenn $b$ ein Kleinbuchstabe ist: | ||
| + | * Verschiebe $b$ um $k$ Positionen im Alphabet | ||
| + | * Hänge $b$ hinten an $r$ an. | ||
| + | * Das Resultat ist $r$. | ||
| + | |||
| + | Was kommt als Resultat mit dem Input $t=$" | ||
| + | |||
| + | |||
| + | ==== Pseudocode allgemein ==== | ||
| + | Pseudocode ist eine Beschreibung eines Algorithmus (Rechenvorschrift, | ||
| + | |||
| + | 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: | ||
| + | * Genaue Beschreibung vom **Input** (Art und womöglich Umfang). | ||
| + | * Genaue Beschreibung vom **Output** (Art und womöglich Umfang). | ||
| + | * Eigentlicher **Algorithmus** | ||
| + | Typische Elemente sind: | ||
| + | * **Variablen**, | ||
| + | * **Wiederholungen** ganzer Programmteile | ||
| + | * Bedingte **Verzweigungen** (wenn das, dann das, sonst jenes) | ||
| + | * **Anweisungen**, | ||
| + | * Evtl. Unterprogramme und/oder Funktionen, um einen Algorithmus in mehrere Algorithmen zu zerlegen. | ||
| + | ===== Python-Code ===== | ||
| + | ==== Einfachste Version ==== | ||
| + | Der Text und der Schlüssel werden direkt im Programm festgelegt. Die Ausgabe erfolgt auf der Konsole. | ||
| + | |||
| + | * Die Funktion '' | ||
| + | * Z.B. liefert '' | ||
| + | * Die Funktion '' | ||
| + | * Z.B. liefert '' | ||
| + | * In Python (und fast allen Programmiersprachen) werden Texte und Zahlen streng unterschieden. So ist '' | ||
| + | |||
| + | <code python caesar1.py> | ||
| + | text = "Hey You!" | ||
| + | key = 3 | ||
| + | |||
| + | result = "" | ||
| + | for symbol in text: | ||
| + | if symbol> | ||
| + | symbol = chr(ord(symbol)+ord(' | ||
| + | if symbol> | ||
| + | nummer = ord(symbol)+key | ||
| + | if nummer< | ||
| + | nummer = nummer+26 | ||
| + | if nummer> | ||
| + | nummer = nummer-26 | ||
| + | symbol = chr(nummer) | ||
| + | result = result + symbol | ||
| + | |||
| + | print(result) | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Gehen Sie in ein geeignetes Verzeichnis (eventuell neu anlegen) und öffnen Sie eine neue Datei in VSCode: | ||
| + | <code bash> | ||
| + | mkdir caesar | ||
| + | cd caesar | ||
| + | code caesar.py | ||
| + | </ | ||
| + | Wenn der Code dann kopiert und gespeichert ist, kann er wie folgt ausgeführt werden: | ||
| + | <code bash> | ||
| + | python caesar.py | ||
| + | </ | ||
| + | </ | ||
| + | ==== In- und Output mit Dateien ==== | ||
| + | Es werden direkt im Programmcode zwei Dateien und der Schlüssel festgelegt: | ||
| + | <code python caesar2.py> | ||
| + | input_datei = " | ||
| + | key = 3 | ||
| + | output_datei = " | ||
| + | |||
| + | # Datei öffnen und einlesen (r für read) | ||
| + | with open(input_datei, | ||
| + | text = f.read() | ||
| + | |||
| + | print(text) | ||
| + | |||
| + | result = "" | ||
| + | for symbol in text: | ||
| + | if symbol> | ||
| + | symbol = chr(ord(symbol)+ord(' | ||
| + | if symbol> | ||
| + | nummer = ord(symbol)+key | ||
| + | if nummer< | ||
| + | nummer = nummer+26 | ||
| + | if nummer> | ||
| + | nummer = nummer-26 | ||
| + | symbol = chr(nummer) | ||
| + | result = result + symbol | ||
| + | |||
| + | print(result) | ||
| + | |||
| + | # Datei überschreiben und ausgeben (w für write) | ||
| + | with open(output_datei," | ||
| + | f.write(result) | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Legen Sie eine Datei '' | ||
| + | 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-/ | ||
| + | </ | ||
| + | |||
| + | ==== Flexiblere Variante mit Kommandozeilenargumenten ==== | ||
| + | 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. | ||
| + | <code python caesar3.py> | ||
| + | import argparse | ||
| + | import sys | ||
| + | import os | ||
| + | |||
| + | # Kommandozeilenoptionen festlegen | ||
| + | parser = argparse.ArgumentParser(description=' | ||
| + | parser.add_argument(' | ||
| + | parser.add_argument(' | ||
| + | parser.add_argument(' | ||
| + | parser.add_argument(' | ||
| + | |||
| + | # Auswerten | ||
| + | args = parser.parse_args() | ||
| + | |||
| + | # Schlüssel bestimmen | ||
| + | key = args.key[0] | ||
| + | if (key<-25 or key>25): | ||
| + | sys.stderr.write(" | ||
| + | exit(-1) | ||
| + | |||
| + | # 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" | ||
| + | exit(-1) | ||
| + | with open(args.infile, | ||
| + | text = f.read() | ||
| + | else: # sonst vom Standard-Input lesen | ||
| + | text = sys.stdin.read() | ||
| + | |||
| + | |||
| + | # Verschleierung | ||
| + | result = "" | ||
| + | for symbol in text: | ||
| + | if symbol> | ||
| + | symbol = chr(ord(symbol)+ord(' | ||
| + | if symbol> | ||
| + | nummer = ord(symbol)+key | ||
| + | if nummer< | ||
| + | nummer = nummer+26 | ||
| + | if nummer> | ||
| + | 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" | ||
| + | exit(-1) | ||
| + | # Datei überschreiben und ausgeben (w für write) | ||
| + | with open(args.outfile, | ||
| + | f.write(result) | ||
| + | else: # Sonst ausgabe auf Standard Ouput | ||
| + | sys.stdout.write(result) | ||
| + | |||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Probieren Sie das Programm auf alle Varianten aus (mit/ohne Input-Datei, | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | 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? | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | Knacken Sie folgenden Text: | ||
| + | <code txt> | ||
| + | bliqvkvokvfyevrsjkrveuvjzeujtynzvizxviqlviirkve | ||
| + | </ | ||
| + | <hidden Lösung auf der Kommandozeile> | ||
| + | In diesem Beispiel ist der verschlüsselte Text in der Datei '' | ||
| + | <code bash> | ||
| + | for a in `seq 1 25`; do echo $a; python caesar3.py -k $a -i humpfdidumpf.txt; | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | **Anspruchsvolle Aufgabe** | ||
| + | |||
| + | Die hier programmierte Verschleierungsmethode ist insofern unschön, dass beim Entschlüsseln nicht unbedingt wieder der Originaltext herauskommt, | ||
| + | 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 '' | ||
| + | </ | ||
| + | |||
| + | <WRAP todo> | ||
| + | **Sehr anspruchsvolle Aufgabe** | ||
| + | |||
| + | Entwerfen Sie eine Methode (erst mal als Pseudocode), | ||
| + | |||
| + | <hidden Hilfe> | ||
| + | * https:// | ||
| + | * http:// | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Entschlüsseln ==== | ||
| + | Laden Sie beide Dateien herunter: {{lehrkraefte: | ||
| + | |||
| + | Verwenden Sie das Programm wie folgt: | ||
| + | <code bash> | ||
| + | python decryptor.py secret.txt | ||
| + | </ | ||
| + | Wobei der zu entschlüsselnde Text in der Datei '' | ||