Шифрование и затем дешифрование той же строки в python - PullRequest
0 голосов
/ 19 февраля 2020

Вот вопрос:

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

В этом вопросе мы реализуем простой шифр подстановки, в котором символ (буква, число или специальный символ) заменяется двумя ди git число от 00 до 99 (включительно). Например, буква «а» может быть зашифрована, чтобы стать номером «06», или специальным символом «!» может стать числом «57».

Мы будем использовать словарь для хранения сопоставления между каждым символом и соответствующей зашифрованной формой. Таким образом, ключи словаря будут обычными символами (буквы, цифры и специальные символы), а значения будут зашифрованными формами символов (два числа git между 00 и 99 ).

Ваш код должен реализовать следующие пять функций для этого вопроса.

  • Имя: создать словарь шифрования

    • Параметры: Нет параметров.
    • Возвращаемое значение: Словарь, в котором каждая клавиша представляет собой обычный символ, а каждое значение представляет собой случайное число из двух чисел git от 00 до 99 включительно.
    • Что он должен делать: В верхней части предоставленного вам кода определена строка LETTERS. Эта строка содержит все буквы, цифры и специальные символы, которые должны быть ключами в словаре. Вам нужно будет l oop над этой строкой и сгенерировать случайное число с двумя числами git между 00 и 99 для каждого символа. Двузначные числа git будут значениями в словаре; каждый символ (ключ) будет иметь одно двузначное число git (значение).
    • Обратите внимание, что числа 0, 1, 2, ..., 9 не должны быть значениями; вместо этого они должны быть числами 00, 01, 02, ..., 09. Кроме того, обратите внимание, что каждый символ должен иметь уникальное случайное число. То есть, если символ «а» соответствует значению «57», ни один другой символ не должен соответствовать значению «57». (Вам нужно будет использовать какое-то l oop, чтобы продолжать генерировать новые случайные числа, пока не будет найдено уникальное.)
  • Имя: encrypt

    • Параметры: Строка s.
    • Возвращаемое значение: Зашифрованная версия строки s. Каждый символ исходной строки s должен быть заменен на соответствующий ему двузначный номер git в словаре шифра.
  • Имя: расшифровать

    • Параметры: Строка s. Возвращаемое значение: дешифрованная версия строки s. Каждое двузначное число git зашифрованной строки s должно быть заменено соответствующим символом в словаре шифра. Обратите внимание, что здесь у нас есть зашифрованная форма (значение в словаре), и мы ищем обычный символ (ключ 7 в словаре). Чтобы сделать это, нам нужно будет использовать функцию обратного просмотра, как показано в классе. Эта функция была предоставлена ​​вам в прилагаемом файле encryption.py.

Мы напишем еще две функции для повышения надежности нашего шифрования. Одна функция будет многократно шифровать строку несколько раз. Другая функция попытается расшифровать строку, не зная, сколько раз она была зашифрована (таким образом, победив точку более сильного шифрования).

  • Имя: шифровать несколько раз

    • Параметры: Строка s и целочисленное значение n для количества раз для шифрования строки.
    • Возвращаемое значение: Строка s зашифрована n раз. Т.е. строка будет зашифрована в первый раз, при этом каждый символ будет преобразован в двумерное представление git. Затем зашифрованная строка будет повторно зашифрована, и каждый di git превратится в свое двойное представление git. (Длина строки, таким образом, удваивается после каждого шифрования.) (Подсказка: вам придется вызывать вашу функцию шифрования несколько раз.)
  • Имя: несколько раз расшифровать

    • Параметры: Строка s.
    • Возвращаемое значение: Дешифрованная версия строки s. Поскольку мы не знаем, сколько раз расшифровывать строку, мы будем продолжать вызывать decrypt для строки, пока строка не будет содержать общее слово на языке Engli sh. Список общих слов, ОБЩИЕ СЛОВА, был предоставлен для вас в файле encryption.py. Если после дешифрования одна строка содержит какое-либо слово из этого списка, вам следует немедленно вернуть дешифрованную строку. В противном случае продолжайте вызывать decrypt для строки, пока она не будет содержать одно из общих слов. (Предположим, что полностью расшифрованная строка всегда будет содержать хотя бы одно общее слово.)

Наконец, в конце файла encryption.py вы заметите некоторые код уже написан для вас. Этот код просит пользователя ввести строку, затем вызывает различные функции и печатает то, что они возвращают (чтобы получить примеры, показанные ниже). Вы должны изменить этот код так, чтобы, если пользователь вводит строку, которая не содержит ни одного слова из списка ОБЩИХ СЛОВ, программа должна вывести «Неверный ввод». и не выполнять остальную часть кода. В противном случае программа должна продолжить работу с остальной частью кода. (Подсказка. Вспомните Задание 1 и ветвления if / else.)

Вот что я попробовал в качестве ввода:

def reverse_lookup(d,v):
    for key in d:
        if d[key]==v:
            return key
    return None

LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-=_+[]{}|;\':",./<>? '
def create_cypher_dictionary():
    random.seed(1337)
    cypher={}

    ar=[0]*100
    for c in LETTERS:
        n=random.randrange(0, 100, 1)
        while ar[n]!=0:
            n=random.randrange(0, 100, 1)
        ar[n]=1
        if n<10:
            cypher[c]=str('0')+str(n)
        else:
            cypher[c]=str(n)

    return cypher

def encrypt(s):
    cypher=create_cypher_dictionary()

    new_s=''
    for c in s:
        new_s=new_s+cypher[c]

    return new_s

def decrypt(s):
    cypher=create_cypher_dictionary()

    new_s=''
    for i in range(len(s)-1):
        c=s[i]+s[i+1]
        for cc in cypher:
            if cypher[cc]==c:
                new_s=new_s+cc

    return new_s

def encrypt_multiple_times(s,n):

    for i in range(n):
        s=encrypt(s)
    return s


COMMON_WORDS= ['the','be','to','of','and','a','in','that','have','I','it','for','not','on','with','he','as','you','do','at']

def check_common_words(s):
    for word in COMMON_WORDS:
        if word in s:
            return False
    return True

def decrypt_multiple_times(s):

    cypher=create_cypher_dictionary()
    while check_common_words(s):
        s=decrypt(s)

    return s


s=input('Enter text to encrypt:')

if check_common_words(s)==False:

    print("Encrypted string:", encrypt(s))
    print("Decrypted string:", decrypt(encrypt(s)))

    salted_s = encrypt_multiple_times(s, 2)

    print("Encrypted x2 string:", salted_s)
    print("Decrypted x2 string:", decrypt_multiple_times(salted_s))

else:
    print('Invalid input.')

И вот результат, который он произвел:

Enter text to encrypt:The quick brown fox jumps over the lazy dog
Encrypted string:   36217337975199904937688489645037748985374251392613378908738437542173378179944437468993
Decrypted string: T0h-eK aq?u(iic,kg CbIr~o@wBn8 Jf~o>x[ fjLusm3p=sK Yocv<e/r" ?tjh-eK Yl-aizyy" fdboig
Encrypted x2 string: 9223712963929263666327296666666282669263230303820366238227629263638203660327926382712729926671232992926303666203639203829263278271296392926303296366668282829263822303666692
Decrypted x2 string: 36 21@7m313p7T997#5W1@9999990+4p9!3p7#6'8'8/4_8T906/45C013p7T7/4_8T9]8#5a3p7/4525W1i3p9N26#1i313p7'8T990_8T7m3_8/413p7#5Y4521@7m313p7'8#1@7T999b4+4+413p7/46'8T999!3

Однако предполагалось вывести:

Enter text to encrypt: The quick brown fox jumps over the lazy dog.
Encrypted string: 0766546138001892056159999714256163973761640073940161973354996169665461919809956156975155
Decrypted string: The quick brown fox jumps over the lazy dog.
Encrypted x2 string: 3417626247536227487834342778713634476227477171717117275336 4762276248711748176227625334341748715334276227711748484753717162276271626247536227712771783471714762274762711747274747
Decrypted x2 string: The quick brown fox jumps over the lazy dog.

У меня действительно нет идей, если кто-то может помочь, это будет очень признательно.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Вы можете попробовать это:

LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-=_+[]{}|;\':",./<>? '

def create_cypher_dictionary():
    numbers = [ '%02d' % i for i in range(100) ]
    random.shuffle( numbers )
    return { a : b for a,b in zip( LETTERS, numbers ) }

def encrypt( cypher, string ) :
    return ''.join( cypher[ch] for ch in string )

def decrypt( cypher, string ) :
    inverse_cypher = { b : a for a,b in cypher.items() }
    return ''.join( inverse_cypher[a+b] for a,b in zip(*[iter(string)]*2) )

Проверка:

>>> cypher = create_cypher_dictionary()
>>> encoded = encrypt( cypher, 'The quick brown fox jumps over the lazy dog' )
>>> encoded
'93684236886025540636378012826636001276363960074903361250428036306842367064856536261211'
>>> decrypt( cypher, encoded )
'The quick brown fox jumps over the lazy dog'
>>> 

И да, вы не можете каждый раз создавать шифр, вы должны его создать и использовать повторно, иначе ваш результаты будут отчасти случайными =)

0 голосов
/ 19 февраля 2020

Вы неправильно конвертируете ASCII, беря только одну ди git за раз, когда вы должны брать две цифры. Просто измените шаг для l oop в вашей функции дешифрования:

def decrypt(s):
    cypher=create_cypher_dictionary()

    new_s=''
    for i in range(0,len(s)-1,2): # Make the for loop step 2 instead of 1 (default)
        c=s[i]+s[i+1]
        for cc in cypher:
            if cypher[cc]==c:
                new_s=new_s+cc

    return new_s
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...