Übung: Decodieren eines Buchstabens nach dem anderen mit einer Cäsar-Chiffre

Abgeschlossen

Erinnern Sie sich an die geheime Botschaft, die Sie entschlüsseln möchten:

Graphic of the encoded secret message.

Anscheinend wurde die Nachricht mit einer sogenannten Caesar-Chiffre verschlüsselt, bei der alle Buchstaben im Alphabet um einen bestimmten Wert verschoben werden. Wir müssen Python die Fähigkeit geben, die wahre Bedeutung der Wörter „Ncevy“, „gpvsui“, „ugflgkg“ und „wjmmf“ zu ermitteln.

Wenn Sie mit Caesar-Chiffren nicht vertraut sind, können Sie auf Smithsonian Learning Labs mehr darüber erfahren.

Um diese Nachricht zu entschlüsseln, müssen Sie Ihren Code zunächst in die Lage versetzen, einen einzelnen Buchstaben zu verschieben. Zuerst erstellen Sie die Funktion lasso_letter(), die zwei Parameter übernimmt. Der erste Parameter ist letter. Er enthält den zu entschlüsselnden Buchstaben. Der zweite Parameter heißt shift_amount und gibt an, wie weit der Buchstabe verschoben werden soll.

def lasso_letter( letter, shift_amount ):

Bevor Sie diese Funktion schreiben, sollten Sie zunächst überlegen, welche Ergebnisse Sie erwarten. Welche Ausgabe erwarten Sie, wenn Sie diese Funktion aufrufen und a als ersten Parameter und 2 als zweiten Parameter übergeben?

Wichtig

Testen Sie dies noch nicht an Ihrem Code! Sie haben die Funktion noch nicht geschrieben.

lasso_letter('a', 2)

Sie erwarten sicher, dass die Funktion den Buchstaben c zurückgibt.

Konvertieren eines Zeichens in eine Zahl

Als Nächstes müssen Sie Ihren Buchstaben (auch als Zeichen oder char bezeichnet) in eine Zahl konvertieren. Buchstaben und Zahlen in Code verfügen über eine numerische Darstellung, da Computer letztendlich Zahlen verarbeiten. ASCII-Zeichencodes sind die numerischen Codes, die Buchstaben und Ziffern darstellen (und andere Interpunktionszeichen, die jedoch den Rahmen dieser Lerneinheit sprengen würden). Im folgenden Diagramm sind die für Menschen verständlichen Buchstaben und Zahlen der jeweiligen Dezimalzahl gegenüberstellt, die Computer verstehen:

Char ASCII Char ASCII Char ASCII           
0 48 Ein 65 a 97
1 49 B 66 b 98
2 50 C 67 c 99
3 51 D 68 T 100
4 52 E 69 e 101
5 53 F 70 f 102
6 54 G 71 g 103
7 55 H 72 h 104
8 56 I 73 i 105
9 57 J 74 j 106
K 75 k 107
L 76 l 108
M 77 m 109
N 78 n 110
O 79 o 111
P 80 p 112
Q 81 q 113
R 82 r 114
E 83 s 115
T 84 t 116
U 85 u 117
V 86 v 118
W 87 w 119
X 88 x 120
J 89 j 121
Z 90 z 122

Hinweis

Diese Tabelle enthält nur Zahlen und Buchstaben, tatsächlich ist jedoch jeder Taste auf der Tastatur ein ASCII-Zeichencode zugeordnet.

Angenommen, Sie übergeben den Buchstaben a und für shift_amount den Wert 2 an die lasso_letter()-Funktion und erwarten die Rückgabe des Buchstabens c. Wie würden Sie Ihren Code anpassen, damit diese Ausgabe zurückgegeben wird?

Das Addieren von a + 2 bringt Sie in diesem Fall nicht weiter. Wie lassen sich eine Zahl und ein Buchstabe überhaupt addieren?

Python ist Ihre Rettung! Denn in Python gibt es die ord-Funktion, die ein Zeichen in seinen entsprechenden ASCII-Zeichencode konvertiert.

Rufen Sie die ord()-Funktion auf, und übergeben Sie den Kleinbuchstaben a:

ord('a')

Die Ausgabe lautet 97. Die Zahl 97 ist der ASCII-Zeichencode des Zeichens a.

Rufen Sie die ord()-Funktion auf, und übergeben Sie den Großbuchstaben N:

ord('N')

Die Ausgabe lautet 78. Die Zahl 78 ist der ASCII-Zeichencode des Zeichens N.

Rufen Sie die ord()-Funktion auf, und übergeben Sie die Zahl 6:

ord('6')

Die Ausgabe lautet 54. Die Zahl 54 ist der ASCII-Zeichencode für die Zahl 6.

Sie konnten zwar nicht einen Buchstaben und eine Zahl miteinander addieren (a + 2), aber Sie können zwei Zahlen addieren. Wenn Sie den Buchstaben a durch 97 ersetzen und mit der Zahl 2 addieren, erhalten Sie 99. Die Zahl 99 ist die ASCII-Darstellung des Zeichens c. Diese Ausgabe sieht sinnvoll aus.

Dies ist der nächste Code, den Sie Ihrer Funktion hinzufügen müssen:

  1. Konvertieren eines Buchstabens zur Vereinheitlichung in einen Kleinbuchstaben
  2. Konvertieren eines Buchstabens in seinen entsprechenden ASCII-Zeichencode mithilfe der ord()-Funktion
def lasso_letter( letter, shift_amount ):
    letter_code = ord(letter.lower())

Wichtig

Achten Sie beim Einfügen des neuen Codes in Ihre Datei darauf, denselben Einzug wie in diesem Beispiel zu verwenden. Ziehen Sie den neuen Code vom linken Rand aus wie gezeigt ein. Wenn der Einzug nicht korrekt ist, liest Python den neuen Code nicht als Teil der Funktion.

Um diese Nachricht zu entschlüsseln, müssen Sie den Buchstaben N um 13 verschieben. Dies sind die Werte für diese Verschiebung, die Sie in Ihren Parametern verwenden:

  • letter = „N“
  • shift_amount = 13
  • letter_code = ord('n') = 110

Berechnen eines decodierten Zeichens: Der einfache Weg

Nun ist es an der Zeit, das neue Zeichen zu berechnen. Sehen Sie sich zunächst das ursprüngliche Beispiel noch einmal an. Wenn Sie vom Buchstaben a aus den Buchstaben c erreichen möchten, führen Sie die folgenden Schritte aus:

  1. Vergewissern Sie sich, dass der im letter-Parameter übergebene Wert ein Kleinbuchstabe ist, indem Sie .lower() aufrufen. In diesem Fall ist der übergebene Buchstabe a. Daher wird er von .lower() als a aufbewahrt.
  2. Verwenden Sie die ord()-Funktion, um den Buchstaben a in seinen ASCII-Code zu konvertieren: 97. Speichern Sie den Codewert 97 in der Variable letter_code.
  3. Addieren Sie 2 als Wert von shift_amount mit dem letter_code-Wert 97, um den neuen Zahlenwert 99 zu erhalten. Speichern Sie den Wert 99 in der Variable decoded_letter_code.
  4. Verwenden Sie die chr()-Funktion, um den Zahlenwert 99 in ein Zeichen zu decodieren und c zu erhalten. (Die chr()-Funktion macht genau das Gegenteil der ord()-Funktion.) Speichern Sie den decodierten Wert c in der Variable decoded_letter.
  5. Geben Sie den Wert von decoded_letter zurück: c.

Ihr Code könnte in etwa wie folgt aussehen:

def lasso_letter( letter, shift_amount ):
    letter_code = ord(letter.lower())
    decoded_letter_code = letter_code + shift_amount
    decoded_letter = chr(decoded_letter_code)
    return decoded_letter

Rufen Sie diese Funktion mithilfe des vorherigen Beispiels auf, um zu überprüfen, ob sie wie erwartet funktioniert:

print(lasso_letter('a', 2))

Das Programm gibt richtigerweise c aus:

Screenshot that shows the output of the letter c.

Es sieht so aus, als würde es funktionieren.

Weitere Tests des Decoders

Auch wenn dieses Beispiel funktioniert, tritt ein Problem auf, wenn Sie das Ende des Alphabets erreichen.

Sehen Sie sich an, was passieren würde, wenn Sie diesen Code mit dem ersten Buchstaben der eigentlichen geheimen Nachricht (N) und dem Betrag 13 für die Verschiebung ausführen.

Variable Wert           
letter N
shift_amount 13
letter_code ord('n') = 110
decoded_letter_code 110 + 13 = 123
decoded_letter chr(123) = {

Der Code gibt nicht das erwartete Ergebnis zurück, da eine Caesar-Chiffre bei Erreichen des Kleinbuchstabens z in einer Schleife zum Kleinbuchstaben a zurückkehrt.

Sie können diesen Code mit Ihrer Funktion ausprobieren:

print(lasso_letter('N', 13))

Die Ausgabe beträgt {.

Screenshot that shows testing the function without using a loop.

Um dieses Schleifenverhalten zu berücksichtigen, müssen Sie die Formel zum Abrufen des decoded_letter_code-Werts ändern. Anstatt einfach den shift_amount-Wert mit letter_code zu addieren, müssen Sie herausfinden, welches der richtige Buchstabencode für den entschlüsselten Buchstaben ist.

Diese Formel sehen Sie sich in der nächsten Lerneinheit an.