Caesar Cipher, расшифровка Python не выводится правильно

Используя алгоритм Casesar Cipher, я пытаюсь заставить его расшифровать все, что я ввожу.

#Decrypt Code
alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ "
DMessage=input("Enter your message to decrypt")
UDMessage=DMessage.upper()
lenDMessage=len(UDMessage)
offset=(int(input("Enter what you would like your offset to be 0,25")))
offset=offset-2
for x in range(0,lenDMessage):
    for y in range(-25,25):
        if UDMessage[x]==alphabet[y+25]:
            print(x,DMessage,[x], UDMessage[x],alphabet[y+25+offset])

Введено Caesar code test run, но получается ecguctbeqfgbvgubbtwp. Кто-нибудь знает, как сделать так, чтобы я мог вернуться назад по алфавиту, чтобы его расшифровать?


person Rohan Smith    schedule 01.05.2015    source источник


Ответы (4)


Я не могу точно сказать реализацию, которую вы использовали для шифрования сообщения, поэтому я предоставляю версию вашего кода, которая сначала шифрует сообщение, а затем берет его и расшифровывает обратно.

Важно понимать, как преобразовать символ в число. Это то, что делает функция ord(). Затем вычитая число для «А», вы можете получить индекс в массиве букв. Вам действительно не нужен массив букв, так как вы можете использовать обратную функцию ord(), которая является функцией chr(), но я оставил реализацию как можно ближе к вашей. Так как "" не находится в последовательности с другими буквами, я выделил этот символ в специальный регистр. С вашим массивом, я думаю, я мог бы использовать вместо этого строковый метод find(), чтобы получить преобразование в число.

Я не знаю, почему вы взяли введенное смещение и вычли из него 2, поэтому я оставил это.

Приведенный ниже код будет зашифровать, а затем расшифровать. Из-за того, как отрицательные индексы работают в Python, вы можете изменить порядок и расшифровать, а затем зашифровать, введя отрицательное смещение вместо положительного.

alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ "
DMessage=input("Enter your message to decrypt")
UDMessage=DMessage.upper()
lenDMessage=len(UDMessage)
offset=(int(input("Enter what you would like your offset to be 0,25")))
encrypted = ''
for letter in UDMessage:
    if letter == ' ':
        index = 26
    else:
        index = ord(letter) - ord('A')
    encrypted += alphabet[index+offset]
print(encrypted)

decrypted = ''
for letter in encrypted:
    if letter == ' ':
        index = 26
    else:
        index = ord(letter) - ord('A')
    decrypted += alphabet[index+27-offset]
print(decrypted)
person Brad Budlong    schedule 01.05.2015

Вы можете использовать метод find, чтобы получить индекс буквы в алфавите и применить к нему смещение. Что-то типа:

import string
alphabet = string.ascii_uppercase + ' '  # more convenient than typing it out
cipher_text = ''
for c in ud_message:  # for each letter in the source message
    index = alphabet.find(c)  # get the alphabet position (A=0, B=1...)
    new_index = (index + offset) % len(alphabet)  # add offset
    cipher_text += alphabet[new_index]  # append it to our cipher_text output

Часть% len (алфавит) предназначена для обертывания индекса. Если буква Z и у них смещение 4, индекс будет 25 + 4 = 29, что больше, чем длина алфавита (26). % Len (алфавит) превращает это в 29% 26 = 3, что превращает Z в D.

Чтобы расшифровать его, вы просто снова выполните метод .find (), но на этот раз вычтите смещение и получите букву, соответствующую этому индексу. Вам не нужно беспокоиться об отрицательных индексах вычитания смещения. В Python отрицательный индекс начинается с другой стороны. Так, например, алфавит [24] - это Y, а алфавит [-2] - тоже Y.

person Phistrom    schedule 01.05.2015

Отказ от ответственности

Этот код работает как бы с Python 3 и не работает как бы с Python 2.

Код

In [1]: def shift(c,n=13,alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"):
        u = c.upper()
        if u not in alphabet: return c
        s = alphabet[(alphabet.index(u)+n)%26] 
        if u!=c: s=s.lower()
        return s
   ...: 

In [2]: def caesar(s,n=13): return "".join(shift(c,n) for c in s)

In [3]: def decaesar(s,n=13): return "".join(shift(c,-n) for c in s)

In [4]: caesar('Puffo Burlone, dove vai?')
Out[4]: 'Chssb Oheybar, qbir inv?'

In [5]: decaesar(_)
Out[5]: 'Puffo Burlone, dove vai?'

In [6]: caesar('Puffo Burlone, dove vai?',22)
Out[6]: 'Lqbbk Xqnhkja, zkra rwe?'

In [7]: decaesar(_,22)
Out[7]: 'Puffo Burlone, dove vai?'

In [8]: caesar('Puffo Burlonè, dovè vai?') # note the accented letters
Out[8]: 'Chssb Oheybaè, qbiè inv?'

In [9]: decaesar(_)
Out[9]: 'Puffo Burlonè, dovè vai?'

Обсуждение

Ядром этого материала является функция shift, которая проверяет, находится ли символ верхнего регистра в alphabet, и если нет, возвращает его как есть, в противном случае сдвигает его на n символа (n может быть отрицательным) вокруг буквенного пончика, как вы get, используя оператор по модулю %, тогда, если c в нижнем регистре, он возвращает сдвинутый символ в нижнем регистре, в противном случае он возвращает сдвинутый символ, который, исходя из алфавита верхнего регистра, имеет верхний регистр.

Затем у нас есть функции caesar и decaesar, которые объединяют сдвинутые символы, взятые из первого обязательного аргумента, необязательный аргумент - это величина сдвига, по умолчанию 13; разница в том, что в decaesar shift вызывается с отрицательным n, так что мы отменяем сдвиг.

В конце концов, мы тестируем наши функции, которые работают также с символами, отличными от ascii, которые остаются одни в зашифрованной строке ... вышесказанное относится к Python 3, кстати, с Python 2 символы, отличные от ascii, искажены.

person gboffi    schedule 01.05.2015

Я взял ваш код и немного переделал. Попробуйте использовать мод вместо того, чтобы расширять строку алфавита, как вы это делали.

#Decrypt Code  DEFGHIJKLMNOPQRSTUVWXYZABC -> ABCDEFGHIJKLMNOPQRSTUVWXYZ  (left 3 offset, -3)
import string
alphabet = string.ascii_uppercase
cipher =  raw_input("Enter your message to decrypt: ").upper()
offset=(int(raw_input("What is the cipher offset? : ")))
plain = []
for letter in cipher:
    offset_letter = alphabet[(alphabet.index(letter) + offset) % len(alphabet)]
    plain.append(offset_letter)
print ''.join(plain)

Вот рабочий сценарий, примечание -3 означает сдвиг влево на 3. Таким образом, вы можете использовать ту же функцию для шифрования / дешифрования, если знаете, как сдвинуть ее:

$Enter your message to decrypt: DEFGHIJKLMNOPQRSTUVWXYZABC
$What is the cipher offset? : -3
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Теперь вернемся в другую сторону, сделав сдвиг вправо:

$Enter your message to decrypt: ABCDEFGHIJKLMNOPQRSTUVWXYZ
$What is the cipher offset? : 3
DEFGHIJKLMNOPQRSTUVWXYZABC

Ваше здоровье

person radtek    schedule 03.05.2015