2017-02-02 3 views
0

Also versuche ich, einen Code zu machen, der jeden Buchstaben in einem Wort um eine Anzahl von Buchstaben im Alphabet zurückversetzt (um das Ende gewickelt). Zum Beispiel, wenn ich um 2 verschieben und CBE eingeben möchte, sollte ich AZC bekommen. oder JOHN in HMFL. Ich habe einen Code für nur einen Brief zu arbeiten, und ich frage mich, ob es ein Weg gibt ein verschachteltes for-Schleife für Python zu tun (das funktioniert?)Implementieren des Caesar-Verschlüsselungsalgorithmus in Python

def move(word, shift): 
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    original = "" 
    for letter in range(26, len(alphabet)): 
    if alphabet[letter] == word: #this only works if len(word) is 0, I want to be able to iterate over the letters in word. 
     original += alphabet[letter-shift] 
    return original 
+0

http://eddmann.com/posts/implementing-rot13-and-rot-n-caesar-ciphers-in-python/ – dabadaba

+0

In welcher Weise diese Arbeit für 1 Brief? –

+0

Nun, das funktioniert einfach für einen Buchstaben, weil Sie von '26' nur einmal über das Alphabet gehen, und die Bedingung wird nur einmal übereinstimmen. –

Antwort

1
A_VAL = ord('a') 

def move(word, shift): 
    new_word = "" 
    for letter in word: 
     new_letter = ord(letter) - shift 
     new_word += chr(new_letter) if (new_letter >= A_VAL) else (26 + new_letter) 
    return new_word 

Beachten Sie, dass dies nur für Kleine Worte funktioniert . Sobald Sie anfangen, Groß- und Kleinbuchstaben zu mischen, müssen Sie anfangen, nach ihnen zu suchen. Aber das ist ein Anfang. Ich habe Ihre Nested-Loop-Idee verworfen, weil Sie diese möglichst vermeiden sollten.

2

Finden Sie nicht den Buchstaben im Alphabet , dass Weg - finden Sie es mit einem Index-Vorgang. Lassen char der Brief in Frage:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
... 
char_pos = alphabet.index(char) 
new_pos = (char_pos - shift) % len(alphabet) 
new_char = alphabet[new_pos] 

Sobald Sie dies verstehen, können Sie diese drei Zeilen in einer einzigen Linie zusammenfallen kann.

Nun, um es auf ein ganzes Wort betreiben zu machen ...

new_word = "" 
for char in word: 
    # insert the above logic 
    new_word += new_char 

Können Sie diese Teile alle zusammen?

Sie müssen immer noch Ihren Scheck sehen, dass char ein Brief ist. Wenn Sie interessiert sind, können Sie auch ein Listenverständnis für alle übersetzten Zeichen erstellen und die Anwendung '. .join() anwenden, um Ihr neues Wort zu erhalten.

Zum Beispiel ...

Wenn der Buchstabe im Alphabet ist (wenn char in Alphabet), die vorgegebene Strecke verschieben und den neuen Brief bekommen, um das Ende Einwickeln bei Bedarf (% 26). Wenn es kein Großbuchstabe ist, verwenden Sie den ursprünglichen Charakter.

Erstellen Sie aus all diesen Übersetzungen eine Liste und fügen Sie sie dann zu einer Zeichenfolge hinzu. Gib diese Zeichenfolge zurück.

def move(word, shift): 
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    return ''.join([alphabet[(alphabet.find(char) - shift) % 26] 
       if char in alphabet else char 
       for char in word]) 

print move("IBM", 1) 
print move("The 1812 OVERTURE is COOL!", 13) 

Ausgang:

HAL 
Ghe 1812 BIREGHER is PBBY! 
+0

Wow, das ist viel eleganter als das, was ich gefunden habe. – Woody1193

5

Sie mögen dieses Grundsätzlich

def move(word, shift): 
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    return "".join([alphabet[alphabet.find(i)-shift] for i in word]) 

beginnen könnte, diese Liste Verständnis erstellt eine Liste der einzelnen Buchstaben. Dann wird der Index des Buchstabens im Alphabet durch die .find-Methode gefunden. Die (Index - Verschiebung) ist der gewünschte neue Index, der aus dem Alphabet extrahiert wird. Die resultierende Liste wird erneut verknüpft und zurückgegeben.

Beachten Sie, dass es offensichtlich nicht auf Eingabezeichenfolgen Kleinbuchstaben funktioniert (wenn Sie möchten, dass die Methode str.upper verwenden). Eigentlich sollte das Wort nur aus Buchstaben bestehen, die im Alphabet vorhanden sind. Für Sätze muss der Ansatz Whitespaces unterschiedlich behandeln.

+0

Dies funktioniert nicht für, sagen wir "B" und eine Verschiebung von 4. Ersetzen Sie ** find ** durch ** rfind **, und ich denke, Sie haben das Mark der Lösung. – Prune

+0

@Prune Können Sie bitte erklären warum? Die erwartete Ausgabe ist 'X' in diesem Fall nein? – Tristan

+0

Ich habe kurz die Indexierung am rechten Ende vergessen; Es funktioniert für Verschiebungen <52. Es wird jedoch einen Indexfehler für alles aus Ihrem Doppelalphabet-Bereich erhalten. Wenn Sie auf einen Wert <26 angewiesen sind, können Sie das zweite Alphabet löschen. – Prune

0

Sie könnten verwenden: chr() geben Sie das Zeichen für eine ASCII-Nummer, ord() geben Sie die ASCII-Nummer für das passende Zeichen.Hier

ist ein altes Vigenere Projekt:

def code_vigenere(ch,cle): 
    text = ch.lower() 
    clef = cle.lower() 
    L = len(cle) 
    res = '' 

    for i,l in enumerate(text): 
     res += chr((ord(l) - 97 + ord(cle[i%L]) - 97)%26 +97) 

    return res 
Verwandte Themen