Caesar-Chiffre Verschiebung mit Anzahl der Buchstaben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Inquisitor_DE
User
Beiträge: 1
Registriert: Donnerstag 30. Januar 2025, 21:26

Hallo liebe Programmierer!
Ich möchte gerade im Rahmen meines Selbststudiums ein Verschlüsselungsprogramm schreiben, bei dem die Verschlüsselung ohne Key funktioniert, aber dafür durch die Anzahl an Buchstaben.
Mein Fehler, der mich sehr beschäftigt ist, dass wenn ein Buchstabe mehrfach auftaucht, immer nur der erste genommen wird und dann so eine falsche Berechnung der Verschlüsselung im Verlauf stattfindet.

Ich habe schon den Beitrag dazu im Forum gelesen und viele Videos auf Yt durchgeguckt, aber nichts hilft so wirklich. Könnte mir einer vielleicht einen Tipp / Hinweis geben woran es liegt? Danke!

Mein Code:

Code: Alles auswählen

'''Das Verschlüsselungsprogramm mit der Cäsar-Chiffre.'''

#Variabeln vereinbaren
klartext = ''
verschiebung = 1

def caesar_verschluesselung(klartext):
    print('Ihr Klartext wird nun verschlüsselt.')
    for zeichen in klartext:
        #Zahl für die Stelle an der das Zeichen steht suchen
        zeichenIndex = klartext.index(zeichen)
        #Verschiebung neu berechnen
        verschiebung = (1 * zeichenIndex) + 1
        #Verschiebung eines Großbuchstabens
        if zeichen.isupper():
            print(chr((ord(zeichen) + verschiebung -65) % 26 + 65), end = ' ')
        elif zeichen == ' ':
            print(' ')
        #Verschiebung eines Kleinbuchstabens
        elif zeichen.islower():
            print(chr((ord(zeichen) + verschiebung - 97) % 26 + 97), end = ' ')
        else:
            return False

#ursprüngliche Zeichenkette einlesen
klartext = input('Bitte geben Sie den Klartext ein, der verschlüsselt werden soll: ')
print('Die ursprüngliche Zeichenkette ist:', klartext, '\n')

#Funktionsaufruf
caesar_verschluesselung(klartext)
Sirius3
User
Beiträge: 18215
Registriert: Sonntag 21. Oktober 2012, 17:20

In Python werden keine Variablen deklariert bzw. vereinbart, wie Du es nennest. Lösche die drei Zeilen am Anfang, die sind unsinnig.

Mach Dir nochmal klar, was klartext.index liefert.
Wenn man neben dem Zeichen auch einen Index braucht, benutzt man `enumerate`.
Die Umrechnung der Zeichen mit ord und chr funktioniert nur für die ASCII-Buchstaben. Das sollte dann in den if-Abfragen so geprüft werden.
Die magischen Zahlen 65 und 97 sind schlecht, weil man nicht erkennen kann, woher diese Zahlen stammen.
Die Funktion liefert False oder None zurück. Das ist komisch. Dass bei False nur ein Teil ausgegeben wird, ist ein weiterer Schwachpunkt.
Statt mit chr, ord und isupper zu arbeiten, würde ich string.ascii_lowercase und string.ascii_uppercase verwenden.
Schreibe eine Funktion, die das Ergebnis per return zurückgibt, als es direkt auszugeben. Im Fehlerfall benutzt man eine Exception, z.B. ValueError.
Benutzeravatar
noisefloor
User
Beiträge: 4149
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Könnte mir einer vielleicht einen Tipp / Hinweis geben woran es liegt?
Das ist halt Standardverhalten von Python, was auch exakt so dokumentiert ist:

"list.index(x[, start[, end]]): Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item." (Link zur Python Doku).

Was du machen könntest ist, dir den letzten Index des jeweiligen Zeichens zu merken und dann das optionale Argument `start` bei der `index` Methode zu setzen. Aber _viel_ einfacher ist der von @Sirius3 genannten Weg via enumerate.

Noch ein Tipp zum Lernen: ich weiß auch, dass YT Videos zum Lernen gucken hip ist und lesen irgendwie out, aber IMHO ist es um Längen effizienter und schneller, erst mal aktiv in der jeweiligen Originaldoku zu Suchen und Lesen statt sich passiv bei YT berieseln zu lassen.

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Für die beiden Zeichenbereiche Klein- und Grossbuchtaben steht da fast der gleiche Code — das vermeidet man normalerweise durch Schleifen und/oder Funktionen.

Code: Alles auswählen

#!/usr/bin/env python3
"""
Verschlüsselung mit einer modifizierten Cäsar-Chiffre.
"""


def text_verschluesseln(klartext):
    verschluesselte_zeichen = []
    for verschiebung, zeichen in enumerate(klartext, 1):
        for start, end in [("A", "Z"), ("a", "z")]:
            assert start <= end
            if start <= zeichen <= end:
                zeichen = chr(
                    (ord(zeichen) - ord(start) + verschiebung)
                    % (ord(end) - ord(start) + 1)
                    + ord(start)
                )
                break

        verschluesselte_zeichen.append(zeichen)

    return "".join(verschluesselte_zeichen)


def main():
    klartext = input(
        "Bitte geben Sie den Klartext ein, der verschlüsselt werden soll: "
    )
    print("Die ursprüngliche Zeichenkette ist:", klartext)
    print("Ihr Klartext wird nun verschlüsselt.")
    print(text_verschluesseln(klartext))


if __name__ == "__main__":
    main()
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
Antworten