Написание грубой силы для шифра Цезера, получение ошибки - PullRequest
0 голосов
/ 02 мая 2018

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

Traceback (most recent call last):
  File "C:\Users\nameredacted\Desktop\Python\CipherV2.py", line 60, in <module>
print(getTranslatedMessage(mode, message, key))
  File "C:\Users\nameredacted\Desktop\Python\CipherV2.py", line 47, in getTranslatedMessage
ciphertext += alpha2[ (alpha1[i] + brutekey)]
KeyError: 26

мой код:

from PyDictionary import PyDictionary
import enchant
MAX_KEY_SIZE = 26
dictionary = PyDictionary()
d = enchant.Dict("en_US")
alpha1 = dict(zip("ABCDEFGHIJKLMNOPQRSTUVWXYZ",range(26)))
alpha2 = dict(zip(range(26),"ABCDEFGHIJKLMNOPQRSTUVWXYZ"))

#gets if the user wants to encrypt or decrypt
def getMode():
  while True:
      print('Do you wish to encrypt, decrypt or brute force a message')
      mode = input().lower()
      if mode in 'encrypt e decrypt d bruteforce bf'.split():
         return mode
      else:
         print('Enter either "encrypt" or "e" or "decrypt" or "d" or "bruteforce" or "bf".')

#gets offset value if needed
def getKey(mode):
 key = 0
 if mode[0]=='b':
       pass
 else: 
       while True:
           key = int(input('Enter the offset number (1-%s)' % (MAX_KEY_SIZE)))
           if (key >= 1 and key <= MAX_KEY_SIZE):
              return key

#translates the message
def getTranslatedMessage(mode, message, key):
  ciphertext=''

  if mode[0] == 'd':
        key = -key
        for c in message.upper():
              if c.isalpha():
                    ciphertext += alpha2[ (alpha1[c] + key)]
              else: ciphertext += c
  elif mode[0] =='e':
        for x in message.upper():
              if x.isalpha():
                    ciphertext += alpha2[ (alpha1[x] + key) ]
              else:
                    ciphertext += x
  else:
        while True:
              for i in message.upper():
                    for brutekey in range (26):
                          ciphertext += alpha2[ (alpha1[i] + brutekey)]
              print(ciphertext)
              if d.check(ciphertext):
                    break

  return ciphertext

mode = getMode()
message = input("please input your message")
key = getKey(mode)
print('Your translated text is:')
print(getTranslatedMessage(mode, message, key))

Спасибо за чтение, также я был бы признателен, если бы вы могли прокомментировать любые улучшения, которые вы можете увидеть.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Итак, я собрал всю помощь ваших парней и вроде как переработал программу. Это немного грязно, но это работает. Код:

from PyDictionary import PyDictionary
import enchant
MAX_KEY_SIZE = 26
Go='Yes'
dictionary = PyDictionary()
d = enchant.Dict("en_US")
alpha1 = dict(zip("ABCDEFGHIJKLMNOPQRSTUVWXYZ",range(26)))
alpha2 = dict(zip(range(26),"ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
#gets if the user wants to encrypt or decrypt
def getMode():
  while True:
      print('Do you wish to encrypt, decrypt or brute force a message')
      mode = input().lower()
      if mode in 'encrypt e decrypt d bruteforce bf'.split():
         return mode
      else:
         print('Enter either "encrypt" or "e" or "decrypt" or "d" or "bruteforce" or "bf".')
#gets offset value
def getKey(mode):
 key = 0
 if mode[0]=='b':
       pass
 else: 
       while True:
           key = int(input('Enter the offset number (1-%s)' % (MAX_KEY_SIZE)))
           if (key >= 1 and key <= MAX_KEY_SIZE):
              return key
#translates the message
def getTranslatedMessage(mode, message, key):
  ciphertext=''

  if mode[0] == 'd':
        key = -key
        for c in message.upper():
              if c.isalpha():
                    ciphertext += alpha2[ (alpha1[c] + key)]
              else: ciphertext += c
  elif mode[0] =='e':
        for x in message.upper():
              if x.isalpha():
                    ciphertext += alpha2[ (alpha1[x] + key)% (MAX_KEY_SIZE) ]
              else:
                    ciphertext += x
  else:
        brutekey=0
        while True:
              for i in message.upper():
                    ciphertext += alpha2[ (alpha1[i] + brutekey)% (MAX_KEY_SIZE)]
              print(ciphertext)
              if d.check(ciphertext):
                    break
              else:
                    ciphertext=''
                    brutekey=brutekey+1

  return ciphertext
while Go=='yes' or 'Yes' or 'YES' or 'YEs' or 'yeS' :
  mode = getMode()
  message = input("please input your message")
  key = getKey(mode)
  print('Your translated text is:')
  print(getTranslatedMessage(mode, message, key))
  Go=input('Would you like to use the cipher again?')
  if Go in 'yes Yes YES YEs yeS':
        pass
  else:
        print("thank you for using the program")
        break
0 голосов
/ 02 мая 2018

Как уже упоминалось в комментарии @TemporalWolf, alpha1[i] + brutekey будет больше 25 в какой-то момент. Предположим, что сообщение "XYZ", а ключ браунтэя, который начинается с 0, будет 2. Тогда alpha1["X"] + brutekey = 25, что нормально. Но alpha2[ alpha1["Y"] + brutekey ] вызовет ошибку KeyError. Чтобы это исправить, вы можете использовать оператор по модулю. Это позволяет вам рассчитывать как с аналоговыми часами: 8 + 6 = 2 (mod 12). В python оператор по модулю представлен %. Ваш код будет:

else:
    while True:
          for i in message.upper():
                for brutekey in range (26):
                      ciphertext += alpha2[ (alpha1[i] + brutekey) % 26]
          print(ciphertext)

Также я думаю, что вы хотите изменить порядок этих двух циклов for. Таким образом, вы исправляете букву сообщения и просматриваете каждый ключ для этого письма. Это просто алфавит.

else:
    for brutekey in range (26):
        for i in message.upper():
            ciphertext += alpha2[ (alpha1[i] + brutekey) % 26]
        print(ciphertext)
        if d.check(ciphertext):
            break
...