Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
| gf_informatik:verschluesselung:caesar [2025-03-17 08:26] – [Aufgabe C2] hof | gf_informatik:verschluesselung:caesar [2026-04-09 06:38] (aktuell) – hof | ||
|---|---|---|---|
| Zeile 4: | Zeile 4: | ||
| {{ : | {{ : | ||
| + | |||
| #### Aufgabe 1: Caesar-Verschlüsselung in Python | #### Aufgabe 1: Caesar-Verschlüsselung in Python | ||
| Zeile 15: | Zeile 16: | ||
| Du kannst über die Buchstaben eines Strings laufen wie über die Elemente einer Liste: | Du kannst über die Buchstaben eines Strings laufen wie über die Elemente einer Liste: | ||
| - | <code python> | + | <html>< |
| + | |||
| + | < | ||
| s = "Hallo KSR" | s = "Hallo KSR" | ||
| for buchstabe in s: | for buchstabe in s: | ||
| print(buchstabe) | print(buchstabe) | ||
| - | </code> | + | </bottom-editor></ |
| Einen String in Grossbuchstaben umwandeln: | Einen String in Grossbuchstaben umwandeln: | ||
| - | <code python> | + | <html>< |
| print(" | print(" | ||
| - | >>> HALLO KSR | + | </ |
| - | </code> | + | |
| Alle Grossbuchstaben können in `string.ascii_uppercase` abgefragt werden. Mit [[https:// | Alle Grossbuchstaben können in `string.ascii_uppercase` abgefragt werden. Mit [[https:// | ||
| - | <code python> | + | <html>< |
| import string | import string | ||
| for buchstabe in " | for buchstabe in " | ||
| print(string.ascii_uppercase.find(buchstabe)) | print(string.ascii_uppercase.find(buchstabe)) | ||
| + | </ | ||
| - | >>> | + | Der Modulo-Operator `%` gibt uns den Rest der Ganzzahl-Division zurück. Das ist praktisch, um den Index wieder bei `A` starten zu lassen, wenn er grösser als `Z` wird: |
| - | 7 | + | |
| - | 0 | + | |
| - | 11 | + | |
| - | 11 | + | |
| - | 14 | + | |
| - | </ | + | |
| - | Der Modulo-Operator `%` gibt uns den Rest der Ganzzahl-Division zurück. Das ist praktisch, um den Index wieder bei `A` starten zu lassen, wenn er grösser als `Z` wird: | + | <html>< |
| - | <code python> | + | |
| import string | import string | ||
| Zeile 54: | Zeile 50: | ||
| ciphertext = string.ascii_uppercase[index] | ciphertext = string.ascii_uppercase[index] | ||
| print(ciphertext) | print(ciphertext) | ||
| - | + | </ | |
| - | >>> C | + | |
| - | </code> | + | |
| <nodisp 1> | <nodisp 1> | ||
| ++++Lösung: | ++++Lösung: | ||
| - | <code python caesar.py> | + | <html>< |
| def caesar(klartext, | def caesar(klartext, | ||
| alphabet = ' | alphabet = ' | ||
| decrypted_text = '' | decrypted_text = '' | ||
| - | # Jeden Buchstaben | + | # Jeden Grossbuchstaben |
| - | for b in klartext: | + | for b in klartext.upper(): |
| # Mit jedem Buchstaben: | # Mit jedem Buchstaben: | ||
| # - Position im Alphabet finden alphabet.find | # - Position im Alphabet finden alphabet.find | ||
| Zeile 81: | Zeile 74: | ||
| print(encrypted) | print(encrypted) | ||
| print(caesar(encrypted, | print(caesar(encrypted, | ||
| - | </code> | + | </bottom-editor></ |
| ++++ | ++++ | ||
| </ | </ | ||
| Zeile 119: | Zeile 112: | ||
| 1. Eine mit der Caesar-Methode verschlüsselte Nachricht kann man problemlos mit Brute-Force entschlüsseln (alle Möglichkeiten ausprobieren). Funktioniert dies bei der monoalphabetische Verschlüsselung auch? Gibt es bessere Möglichkeiten, | 1. Eine mit der Caesar-Methode verschlüsselte Nachricht kann man problemlos mit Brute-Force entschlüsseln (alle Möglichkeiten ausprobieren). Funktioniert dies bei der monoalphabetische Verschlüsselung auch? Gibt es bessere Möglichkeiten, | ||
| - | < | + | < |
| ++++Lösung| | ++++Lösung| | ||
| Für den ersten Buchstaben A können wir unter 26 Möglichkeiten auswählen, um ihn umzuplatzieren. Für B bleiben noch 25, für C 24 Möglichkeiten, | Für den ersten Buchstaben A können wir unter 26 Möglichkeiten auswählen, um ihn umzuplatzieren. Für B bleiben noch 25, für C 24 Möglichkeiten, | ||
| Zeile 138: | Zeile 131: | ||
| ++++ | ++++ | ||
| - | < | + | < |
| ++++Mehr Tipps| | ++++Mehr Tipps| | ||
| - | <code python> | + | <html>< |
| def decrypt(ciphertext, | def decrypt(ciphertext, | ||
| # oder string.ascii_uppercase | # oder string.ascii_uppercase | ||
| Zeile 159: | Zeile 152: | ||
| key = " | key = " | ||
| print(decrypt(ciphertext, | print(decrypt(ciphertext, | ||
| - | </code> | + | </bottom-editor></ |
| ++++ | ++++ | ||
| </ | </ | ||
| - | < | + | < |
| ++++Lösung| | ++++Lösung| | ||
| - | <code python> | + | <html>< |
| def decrypt(ciphertext, | def decrypt(ciphertext, | ||
| # oder string.ascii_uppercase | # oder string.ascii_uppercase | ||
| Zeile 183: | Zeile 176: | ||
| key = " | key = " | ||
| print(decrypt(ciphertext, | print(decrypt(ciphertext, | ||
| - | </code> | + | </bottom-editor></ |
| ++++ | ++++ | ||
| </ | </ | ||
| Zeile 256: | Zeile 249: | ||
| ``` | ``` | ||
| ++++ | ++++ | ||
| - | < | + | |
| + | < | ||
| ++++Python Lösung| | ++++Python Lösung| | ||
| - | <code python> | + | <html>< |
| import string | import string | ||
| Zeile 301: | Zeile 295: | ||
| print(f" | print(f" | ||
| + | faust = 'Habe nun, ach! Philosophie, | ||
| print_percentages(count_letters(faust)) | print_percentages(count_letters(faust)) | ||
| - | </code> | + | </bottom-editor></ |
| ++++ | ++++ | ||
| </ | </ | ||
| Zeile 309: | Zeile 304: | ||
| ##### Option 2: Häufigkeitsanalyse von ganzem Buch (anspruchsvoll) | ##### Option 2: Häufigkeitsanalyse von ganzem Buch (anspruchsvoll) | ||
| - | Wie in Option 1, nur soll anstelle eines einzelnen Strings ein ganzes Buch eingelesen und analysiert werden. Auf [[https:// | + | Wie in Option 1, nur soll anstelle eines einzelnen Strings ein ganzes Buch eingelesen und analysiert werden. Auf [[https:// |
| - | <code python> | + | Damit das auch im Browser funktioniert, |
| - | from urllib.request | + | * Erste 5000 Zeichen von Faust: [[https:// |
| - | count = 0 | + | * Gesamter Faust 1 (ca. 220KB): [[https:// |
| - | data = urlopen(<Pfad zur Datei>) | + | * Manns "Tod in Venedig" |
| - | text = data.read().decode(' | + | |
| - | </code> | + | <html>< |
| + | from pyodide.http import | ||
| + | url = ' | ||
| + | response | ||
| + | faust = await response.text() | ||
| + | |||
| + | print(faust[:116]) | ||
| + | </bottom-editor></ | ||
| Kontrolle: am häufigsten vorkommen sollte $E$ (gut $15\%$), gefolgt von $N$ (ca. $10\%$) und $S$. Die letzten Ränge machen typischerweise $Y$, $Q$ und $X$ unter sich aus. | Kontrolle: am häufigsten vorkommen sollte $E$ (gut $15\%$), gefolgt von $N$ (ca. $10\%$) und $S$. Die letzten Ränge machen typischerweise $Y$, $Q$ und $X$ unter sich aus. | ||
| - | < | + | < |
| ++++Lösung mit Gutenberg| | ++++Lösung mit Gutenberg| | ||
| - | <code python> | + | <html>< |
| - | # Rest as above. | + | import string |
| - | from urllib.request import urlopen | + | |
| - | + | def normalize(text): | |
| - | faust = urlopen(' | + | """ |
| - | s= faust.read().decode(' | + | text = text.lower() |
| - | print_percentages(count_letters(s)) | + | text = text.replace(' |
| - | </code> | + | |
| + | text = text.replace(' | ||
| + | return text | ||
| + | |||
| + | def count_letters(text): | ||
| + | """ | ||
| + | # 1: Prepare empty data | ||
| + | alphabet = string.ascii_lowercase | ||
| + | counts = [0] * len(alphabet) | ||
| + | total = 0 | ||
| + | |||
| + | # 2: Count occurrences | ||
| + | for letter in text: | ||
| + | letter = normalize(letter) | ||
| + | index = alphabet.find(letter) | ||
| + | # find() returns negative numbers if not found | ||
| + | # (punctuation etc.) -> ignore these. | ||
| + | if index >= 0: | ||
| + | counts[index] = counts[index] + 1 | ||
| + | total = total + 1 | ||
| + | |||
| + | # 3: Divide by total to get relative frequencies. | ||
| + | for i in range(len(counts)): | ||
| + | counts[i] = counts[i] / total | ||
| + | |||
| + | return counts | ||
| + | |||
| + | def print_percentages(counts): | ||
| + | """ | ||
| + | for i in range(len(counts)): | ||
| + | letter = string.ascii_lowercase[i] | ||
| + | percent = counts[i] | ||
| + | # Print the letter with width 2 | ||
| + | # Print the frequency with width 6 and precision 2, in percent format. | ||
| + | print(f" | ||
| + | |||
| + | from pyodide.http import pyfetch | ||
| + | url = 'https://bottom.ch/ksr/crypto/faust.txt' | ||
| + | response | ||
| + | faust = await response.text() | ||
| + | print_percentages(count_letters(faust)) | ||
| + | |||
| + | </bottom-editor></ | ||
| ++++ | ++++ | ||
| </ | </ | ||