Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
gf_informatik:verschluesselung:caesar [2025-03-09 16:47] – [Aufgabe B2] hofgf_informatik:verschluesselung:caesar [2026-03-12 09:18] (aktuell) – [Aufgabe C2] hof
Zeile 4: Zeile 4:
  
 {{ :gf_informatik:caesar.png?nolink&400 |}} {{ :gf_informatik:caesar.png?nolink&400 |}}
 +
 #### 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><script type="module" src="https://bottom.ch/ksr/ed/bottom-editor.js"></script></html> 
 +  
 +<html><bottom-editor>
 s = "Hallo KSR" s = "Hallo KSR"
 for buchstabe in s: for buchstabe in s:
     print(buchstabe)     print(buchstabe)
-</code>+</bottom-editor></html>
  
 Einen String in Grossbuchstaben umwandeln: Einen String in Grossbuchstaben umwandeln:
  
-<code python>+<html><bottom-editor>
 print("Hallo KSR".upper()) print("Hallo KSR".upper())
->>> HALLO KSR +</bottom-editor></html>
-</code>+
  
 Alle Grossbuchstaben können in `string.ascii_uppercase` abgefragt werden. Mit [[https://docs.python.org/3/library/stdtypes.html?highlight=upper#str.find|str.find()]] können wir den Index (oder -1) finden: Alle Grossbuchstaben können in `string.ascii_uppercase` abgefragt werden. Mit [[https://docs.python.org/3/library/stdtypes.html?highlight=upper#str.find|str.find()]] können wir den Index (oder -1) finden:
  
-<code python>+<html><bottom-editor>
 import string import string
  
 for buchstabe in "HALLO": for buchstabe in "HALLO":
     print(string.ascii_uppercase.find(buchstabe))     print(string.ascii_uppercase.find(buchstabe))
 +</bottom-editor></html>
  
->>> +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:
-+
-+
-11 +
-11 +
-14 +
-</code>+
  
-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><bottom-editor>
-<code python>+
 import string import string
  
Zeile 54: Zeile 50:
 ciphertext = string.ascii_uppercase[index] ciphertext = string.ascii_uppercase[index]
 print(ciphertext) print(ciphertext)
- +</bottom-editor></html>
->>+
-</code>+
  
 <nodisp 2> <nodisp 2>
 ++++Lösung:| ++++Lösung:|
-<code python caesar.py> +<html><bottom-editor
-import string +def caesar(klartextn): 
- +    alphabet 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,!?' 
-def caesar(textkey): +    decrypted_text = '' 
-    ciphertext "" +    # Jeden Grossbuchstaben b im Klartext durchgehen. for-Schleife 
-    for letter in text.upper(): +    for in klartext.upper(): 
-        index string.ascii_uppercase.find(letter+    # Mit jedem Buchstaben: 
-        if index != -1:  # -1 means not found +    #   - Position im Alphabet finden alphabet.find 
-            index index key +        alphabet.find(b
-            index index % len(string.ascii_uppercase) +      Position um n verschieben (Addition oder Subtraktion) 
-            letter = string.ascii_uppercase[index] +        n 
-        ciphertext ciphertext letter +    #   - Resultat eingrenzen auf 0...len(alphabet) 
-    return ciphertext+        p % len(alphabet
 +        decrypted_text decrypted_text alphabet[p] 
 +    return decrypted_text
  
 key = 17 key = 17
Zeile 78: Zeile 74:
 print(encrypted) print(encrypted)
 print(caesar(encrypted, -key)) print(caesar(encrypted, -key))
-</code>+</bottom-editor></html>
 ++++ ++++
 </nodisp> </nodisp>
 +
 #### Aufgabe 2 #### Aufgabe 2
  
Zeile 134: Zeile 131:
 ++++ ++++
  
-<nodisp 2>+<nodisp 1>
 ++++Mehr Tipps| ++++Mehr Tipps|
-<code python>+<html><bottom-editor>
 def decrypt(ciphertext, key): def decrypt(ciphertext, key):
     # oder string.ascii_uppercase     # oder string.ascii_uppercase
Zeile 155: Zeile 152:
 key = "UELXBICNYAZJSQORTPKFMGVHWD" key = "UELXBICNYAZJSQORTPKFMGVHWD"
 print(decrypt(ciphertext, key)) print(decrypt(ciphertext, key))
-</code>+</bottom-editor></html>
 ++++ ++++
 </nodisp> </nodisp>
Zeile 161: Zeile 158:
 <nodisp 2> <nodisp 2>
 ++++Lösung| ++++Lösung|
-<code python>+<html><bottom-editor>
 def decrypt(ciphertext, key): def decrypt(ciphertext, key):
     # oder string.ascii_uppercase     # oder string.ascii_uppercase
Zeile 179: Zeile 176:
 key = "UELXBICNYAZJSQORTPKFMGVHWD" key = "UELXBICNYAZJSQORTPKFMGVHWD"
 print(decrypt(ciphertext, key)) print(decrypt(ciphertext, key))
-</code>+</bottom-editor></html>
 ++++ ++++
 </nodisp> </nodisp>
Zeile 265: Zeile 262:
     return text     return text
          
- 
 def count_letters(text): def count_letters(text):
     """Computes relative frequency of lower-case ASCII letters in text."""     """Computes relative frequency of lower-case ASCII letters in text."""
Zeile 296: Zeile 292:
         # Print the letter with width 2         # Print the letter with width 2
         # Print the frequency with width 6 and precision 2, in percent format.         # Print the frequency with width 6 and precision 2, in percent format.
-        print("{0:2}{1:6.2%}".format(letter, percent))+        print(f"{letter:2}{percent:6.2%}")
  
 print_percentages(count_letters(faust)) print_percentages(count_letters(faust))
Zeile 306: Zeile 302:
 ##### 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://www.gutenberg.org|Project Gutenberg]] findest du über $60'000$ gratis Ebooks. Wähle ein Buch aus und klicke dann auf "Plain Text UTF-8". Das Buch erscheint dann im einfachen Textformat direkt im Browser. Über den dazugehörigen Linkkannst du das Buch direkt in Python einlesen:+Wie in Option 1, nur soll anstelle eines einzelnen Strings ein ganzes Buch eingelesen und analysiert werden. Auf [[https://www.gutenberg.org|Project Gutenberg]] findest du über $60'000$ gratis Ebooks. Wähle ein Buch aus und klicke dann auf "Plain Text UTF-8". Das Buch erscheint dann im einfachen Textformat direkt im Browser. Über den dazugehörigen Link kannst du das Buch direkt in Python einlesen.
  
-<code python> +Damit das auch im Browser funktioniert, können die Texte auch von folgenden Orten benutzt werden: 
-import urllib2+  * Erste 5000 Zeichen von Faust: [[https://bottom.ch/ksr/crypto/faust_5000.txt]] 
 +  * Gesamter Faust 1 (ca. 220KB): [[https://bottom.ch/ksr/crypto/faust.txt]] 
 +  * Manns "Tod in Venedig" (ca. 190KB): [[https://bottom.ch/ksr/crypto/tod_in_venedig.txt]]
  
-data = urllib2.urlopen(<Pfad zu File als String>) +<html><bottom-editor
-line_first = ... # erste Zeile des Texts +from pyodide.http import pyfetch 
-line_last  = ... # letzte Zeile des Texts +url 'https://bottom.ch/ksr/crypto/faust_5000.txt' 
-for line in data: +response await pyfetch(url
-    line line.replace('\n', '').decode('utf-8') # replace(...): entfernt nervige Zeilenumbrueche, decode(): Umlaute usw richtig anzeigen +faust await response.text()
-    if line_first <count <= line_last: +
-        print(line# Achtung: keine gute Idee, wenn File sehr viele Zeilen beinhaltet! Baue z.B. Counter ein, damit nach z.B. 100 Ausgaben abbricht +
-</code>+
  
-Beachte, dass du noch die erste und letzte Zeilennummer im Buch angeben musstDer Text am Anfang und Ende des Files gehört nicht zum Buch und soll ignoriert werden.+print(faust[:116]) 
 +</bottom-editor></html>
  
 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.
Zeile 326: Zeile 322:
 <nodisp 2> <nodisp 2>
 ++++Lösung mit Gutenberg| ++++Lösung mit Gutenberg|
-<code python> +<html><bottom-editor> 
-# Rest as above. +import string
-# Trick: urlopen() returns a file-like object, which iterates over lines of text +
-# itertools.chain.from_iterable() will create an iterator that takes those lines +
-# and iterates over each of them (creating an iterator over the characters of the +
-# entire book).+
  
-Cautionthis solution will not properly decode UTF-8 characters.+def normalize(text): 
 +    """Replaces umlauts with base characters, and lower-case variants.""" 
 +    text = text.lower() 
 +    text = text.replace('ä', 'a'
 +    text = text.replace('ö', 'o'
 +    text = text.replace('ü', 'u'
 +    return text 
 +     
 +def count_letters(text): 
 +    """Computes relative frequency of lower-case ASCII letters in text.""" 
 +    1Prepare empty data 
 +    alphabet = string.ascii_lowercase 
 +    counts = [0] * len(alphabet)  # Creates [0, 0, ..., 0] 
 +    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
  
-import urllib2 +def print_percentages(counts): 
-import itertools+    """Pretty-print frequency data.""" 
 +    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"{letter:2}{percent:6.2%}"
 + 
 +from pyodide.http import pyfetch 
 +url = 'https://bottom.ch/ksr/crypto/faust.txt' 
 +response = await pyfetch(url) 
 +faust = await response.text() 
 +print_percentages(count_letters(faust)) 
 + 
 +</bottom-editor></html>
  
-faust = urllib2.urlopen('https://www.gutenberg.org/files/21000/21000-0.txt') 
-print_percentages(count_letters(itertools.chain.from_iterable(faust))) 
-</code> 
 ++++ ++++
 </nodisp> </nodisp>
  • gf_informatik/verschluesselung/caesar.1741538878.txt.gz
  • Zuletzt geändert: 2025-03-09 16:47
  • von hof