2017-05-08 7 views
1

Ich bin eine Caesar-Chiffre. Der Schlüssel ist eine ganze Zahl von 1 bis 25. Diese Chiffre rotiert die Buchstaben des Alphabets (A bis Z). Die Kodierung ersetzt jeden Buchstaben durch den 1. bis 25. nächsten Buchstaben im Alphabet (Z von A umwickeln). Also verschlüsselt der Schlüssel 2 "HI" mit "JK", aber der Schlüssel 20 verschlüsselt "HI" mit "BC".Zurück zum Anfang einer Zeichenfolge

Aber wenn ich "Ich bin super" eingeben, wird es "k kc oouwrgt" ausgeben, wenn es "k co uwrgt" mit einer Taste von 2 sein soll. Es wird auch nicht zum Anfang des Alphabets zurückkehren zB 'x' geht nicht zu 'a' mit einem Schlüssel von 2. ich benutze python 3.4.1

encode = [] 
a = "abcdefghijklmnopqrstuvwyxz" 
a = list(a) 
print(a) 

e = input("encode or decode --->") 
text = input("Sentence -->").lower() 
text = list(text) 
print(text) 


Key = int(input("Key -->")) 
if Key > 25: 
    print("Too high") 
else: 
    print(Key) 

if e == "encode": 
    for i, item in enumerate(text): 
     if item == " ": 
      encode.append(letter) 
     else: 
      num = a.index(item) 
      num = num + int(Key) 
      letter = a[num] 
      encode.append(letter) 

for i in range(len(encode)): 
    print(encode[i]) 

Antwort

0

eine offensichtliche Lösung wäre modulo für den Alphabet-Index zu verwenden:

des % (Modulo) -Operator ergibt den Rest aus der Division des ersten Arguments durch das zweite Argument .

>>> 12 % 26 
12 
>>> 26 % 26 
0 
>>> 28 % 26 
2 

Als Bonus, würden Sie nicht brauchen, ist der Schlüssel zu überprüfen, ist niedriger als 25 ist, und Sie werden nie eine IndexError: list index out of range bekommen.

encode = [] 
a = "abcdefghijklmnopqrstuvwyxz" 

e = input("encode or decode --->") 
text = input("Sentence -->").lower() 

key = int(input("Key -->")) 

if e == "encode": 
    for i, item in enumerate(text): 
     if item == " ": 
      encode.append(item) 
     else: 
      num = a.index(item) 
      num = num + int(key) 
      letter = a[num % 26] 
      encode.append(letter) 

for letter in encode: 
    print(letter) 

Ein paar Anmerkungen:

  • ein String ist bereits ein iterable von Zeichen. Keine Notwendigkeit, sie in eine Liste zu konvertieren
  • letter nicht in if item == " "
  • definiert wurde, eine Liste zu iterieren, müssen Sie die Länge oder den Index nicht benötigen.
  • um die Nachricht zu entschlüsseln, ändern Sie einfach das Vorzeichen des Schlüssels. Es sollte wie kodieren, durch Modulo arbeiten: -2 % 26 # => 24

Als Beispiel:

encode or decode --->encode 
Sentence -->i am super 
Key -->2 
k 

c 
o 

u 
w 
r 
g 
t 

und

encode or decode --->encode 
Sentence -->k co uwrgt 
Key -->-2 
i 

a 
m 

s 
u 
p 
e 
r 
4

Wenn Sie einen Raum begegnen, fügen Sie den letzten Buchstaben wieder, statt item:

if item == " ": 
    encode.append(letter) 

Dies führt dazu, dass k und o zweimal erscheinen, wenn der Schlüssel 2 ist; Sie haben die codierten i ->k und m ->o Ergebnisse wieder angehängt.

Sie müssen die % modulo operator verwenden, um Ihren Index zu machen ‚umwickeln‘:

num = (num + Key) % 26 

ich den int() Anruf entfernt, haben Sie bereits Key früher eine ganze Zahl gedreht.

Weitere Tipps:

  • Sie brauchen nicht a in eine Liste zu machen; Zeichenketten sind auch Sequenzen und unterstützen die Indizierung und die .index() Methode direkt. Gleiches gilt für text; Schleife einfach über die Saite selbst.

  • Sie verwenden i nicht in der for i, item in enumerate(text): Schleife; Tropfen enumerate insgesamt: for item in text:.

  • Sie könnte nur Ihre codierten Zeichen gedruckt werden direkt in dieser Schleife, keine Notwendigkeit, eine encode Liste und eine separate Schleife verwenden.

  • Mit der str.join() method können Sie Ihren codierten Text alle in einer Zeile: print(''.join(encode)) anstelle Ihrer letzten for Schleife.

  • Die absolute schnellste Methode eine Reihe von Kodierung ist eine Übersetzungstabelle , ein Wörterbuch Abbildungseingabezeichen zu Ausgabezeichen zu verwenden, und die str.translate() method. Sie können die str.maketrans() function verwenden, um die Tabelle zu machen:

    import string 
    
    a = string.ascii_lowercase # why type yourself when the stdlib has these? 
    text = input("Sentence -->").lower() 
    Key = int(input("Key -->")) 
    mapping = str.maketrans(a, a[Key:] + a[:Key]) # letters to rotated letters 
    print(text.translate(mapping)) 
    

    Der Trick liegt in den zweiten String für str.maketrans() zu schaffen; mit dem Schneiden wird es einfach, eine gedrehte Schnur zu schaffen, durch Key weiter alles von Position einnehmen, und die ersten Key Zeichen am Ende:

    >>> a[Key:] + a[:Key] 
    'cdefghijklmnopqrstuvwyxzab' 
    
+0

'a [Key:] + a [: Key]' ist ein cooler Trick, es funktioniert auch mit negativen Indizes zum Decodieren. –

+0

@EricDuminil: oder einfach 'str.translate (a [Key:] + a [: Key], a)'. –

+0

Das ist großartig, danke, dass du dir die Zeit genommen hast, es zu erklären :) – jennmaurice

Verwandte Themen