So funktioniert der Code
Die Schleife liest den Text Zeichen für Zeichen. ord() macht aus einem Buchstaben eine Zahl: ord("A") ist 65 und ord("a") ist 97. Ziehst du diese Basis ab, erhältst du die Position im Alphabet, von 0 bis 25.
Nach dem Addieren der Verschiebung sorgt % 26 dafür, dass es am Ende des Alphabets vorne weitergeht: Bei der Verschiebung 3 landet Z auf C. chr() wandelt die Zahl wieder in einen Buchstaben um. Ist die Chiffre selbst noch neu für dich, hilft die Anleitung ganz ohne Code.
Leerzeichen, Satzzeichen und Ziffern laufen durch den else-Zweig und bleiben unverändert. Das gilt auch für Umlaute und ß. Dafür ist isascii() da: Ohne diese Prüfung hält Python ä für einen normalen Kleinbuchstaben, macht daraus irgendeinen Buchstaben von A bis Z, und der Text lässt sich nicht mehr korrekt entschlüsseln.
Entschlüsseln in Python
Eine zweite Funktion brauchst du nicht. Entschlüsseln ist dieselbe Verschiebung in die andere Richtung, also übergibst du eine negative Zahl:
print(caesar("Kdoor Zhow!", -3))# Hallo Welt!Das klappt, weil % in Python hier nie negativ wird: (0 - 3) % 26 ergibt 23, und A geht zurück zu X. In C, Java und JavaScript käme -3 heraus, deshalb braucht die JavaScript-Version einen Zwischenschritt.
Programm mit Benutzereingabe
Oft verlangt eine Aufgabe ein Programm, das Text und Verschiebung über die Tastatur einliest. Schreib das unter die Funktion:
text = input("Text: ")shift = int(input("Verschiebung: "))mode = input("Verschlüsseln oder entschlüsseln? (v/e): ") if mode == "e": shift = -shift print(caesar(text, shift))input() liefert immer einen String, deshalb muss die Verschiebung durch int(). Tippt jemand ein Wort statt einer Zahl, bricht Python mit einem ValueError ab.
Die Chiffre mit Brute Force knacken
Bei 26 Buchstaben gibt es nur 25 Verschiebungen zum Ausprobieren, also liest eine kurze Schleife die Nachricht auch ohne Schlüssel. Du musst nur die Zeile finden, die einen Sinn ergibt:
def crack(text): for shift in range(1, 26): print(shift, caesar(text, -shift)) crack("Kdoor Zhow!")# 1 Jcnnq Ygnv!# 2 Ibmmp Xfmu!# 3 Hallo Welt!# ...Mehr dazu steht im Artikel über den Brute-Force-Angriff, und der Caesar-Knacker erledigt dasselbe im Browser.
Kürzer mit str.translate
Sobald du die Schleife verstanden hast, kannst du sie durch eine Übersetzungstabelle ersetzen. str.maketrans() ordnet jedem Buchstaben seine verschobene Form zu, und translate() wendet die Tabelle auf den ganzen Text an. Umlaute bleiben auch hier unberührt.
from string import ascii_lowercase as lower, ascii_uppercase as upper def caesar(text, shift): shift %= 26 table = str.maketrans( lower + upper, lower[shift:] + lower[:shift] + upper[shift:] + upper[:shift], ) return text.translate(table)Die Ergebnisse sind identisch, und bei langen Texten ist das meist schneller, weil die Tabelle nur einmal entsteht. Für die erste Hausaufgabe lässt sich die Schleife aber leichter erklären.
Caesar mit Umlauten und ß
Sollen auch ä, ö, ü und ß verschoben werden, legst du das Alphabet als String ab und suchst jedes Zeichen mit index(). Das sind dieselben 30 Zeichen wie in unserem Tool:
ALPHABET = "aäbcdefghijklmnoöpqrstuüvwxyzß" def caesar_alphabet(text, shift): result = "" for char in text: letter = char.lower() if letter in ALPHABET: index = (ALPHABET.index(letter) + shift) % len(ALPHABET) new = ALPHABET[index] result += new.upper() if char.isupper() else new else: result += char return result print(caesar_alphabet("Schöne Grüße", 3))# Üfkrph JuxbhDer Umlauf nutzt jetzt len(ALPHABET), die 30 musst du also nirgends eintragen. Eine Besonderheit hat das ß: "ß".upper() ergibt in Python SS, ein Großbuchstabe, der auf ß fällt, wird also zu zwei Zeichen. Vergleichen kannst du das Ergebnis im Caesar-Tool mit dem deutschen Alphabet.
Eine Textdatei verschlüsseln
Lies die Datei ein, gib ihren Inhalt an die Funktion und schreib das Ergebnis in eine neue Datei. Mit encoding="utf-8" bleiben Umlaute auf jedem System erhalten.
with open("message.txt", encoding="utf-8") as source: text = source.read() with open("encrypted.txt", "w", encoding="utf-8") as target: target.write(caesar(text, 3))Dieselbe Chiffre als Klasse
Eine Klasse lohnt sich, wenn du einen Schlüssel oft verwendest oder objektorientierter Code verlangt ist. Sie speichert die Verschiebung und nutzt die Funktion vom Anfang der Seite:
class CaesarCipher: def __init__(self, shift=3): self.shift = shift def encrypt(self, text): return caesar(text, self.shift) def decrypt(self, text): return caesar(text, -self.shift) cipher = CaesarCipher(5)print(cipher.encrypt("Hallo Welt!"))# Mfqqt Bjqy!Den Code testen
Ein paar assert-Zeilen finden die meisten Fehler: das Überschreiten von Z, Groß- und Kleinschreibung, Satzzeichen und die Rückkehr zum Ausgangstext. Ist alles in Ordnung, gibt das Programm OK aus.
assert caesar("ABC", 3) == "DEF"assert caesar("xyz", 3) == "abc"assert caesar("Hello, World!", 5) == "Mjqqt, Btwqi!"assert caesar(caesar("Python", 7), -7) == "Python"assert caesar("A", 26) == "A"assert caesar("é", 3) == "é"print("OK")Häufige Fehler
Der Klassiker ist chr(ord(char) + shift) ohne Modulo: Z wird bei der Verschiebung 3 dann zum Zeichen ]. Ebenso häufig ist die Basis 65 für alle Buchstaben, was Kleinbuchstaben zerstört. Und wer int() um input() vergisst, bekommt beim Addieren der Verschiebung einen TypeError.
Häufige Fragen
Welche Python-Version brauche ich?
Python 3.7 oder neuer, denn seitdem gibt es isascii(). Wir haben den Code dieser Seite mit Python 3.9 ausgeführt. Zusätzliche Pakete sind nicht nötig.
Kann ich damit echte Daten schützen?
Nein. Die Schleife von oben knackt die Chiffre in Sekunden. Nimm sie zum Lernen und für Rätsel. Für Passwörter und private Daten brauchst du moderne Verschlüsselung aus einer gepflegten Bibliothek.
Wie prüfe ich, ob mein Ergebnis stimmt?
Gib denselben Text und dieselbe Verschiebung in unser Caesar-Tool ein und vergleiche. Aus deinen Tests heraus kannst du auch die kostenlose REST-API aufrufen.