https://en.wikipedia.org/wiki/Caesar_cipher
嘿所有,我这样做是为了Uni的任务。我已经接近完成,但我仍然坚持到最后一节。我确定这是基本的,但我花了将近四个小时试图使用print语句找到我的错误。
基本上,我们的想法是通过循环遍历所有-26个偏移来强行解密用户的加密消息。我的问题是我可以让代码循环26次,但它根本不会为每个偏移量解密消息..如果这是有道理的。
正确的样品输出:
Please enter string to decrypt: ykixkz&yw{oxxkr
Offset: -1 = Decrypted string: xjhwjy%xvznwwjq
Offset: -2 = Decrypted string: wigvix$wuymvvip
Offset: -3 = Decrypted string: vhfuhw#vtxluuho
Offset: -4 = Decrypted string: ugetgv"uswkttgn
Offset: -5 = Decrypted string: tfdsfu!trvjssfm
Offset: -6 = Decrypted string: secret squirrel
Offset: -7 = Decrypted string: rdbqds}rpthqqdk
Offset: -8 = Decrypted string: qcapcr|qosgppcj
Offset: -9 = Decrypted string: pb`obq{pnrfoobi
Offset: -10 = Decrypted string: oa_napzomqennah
Offset: -11 = Decrypted string: n`^m`oynlpdmm`g
Offset: -12 = Decrypted string: m_]l_nxmkocll_f
Offset: -13 = Decrypted string: l^\k^mwljnbkk^e
Offset: -14 = Decrypted string: k][j]lvkimajj]d
Offset: -15 = Decrypted string: j\Zi\kujhl`ii\c
Offset: -16 = Decrypted string: i[Yh[jtigk_hh[b
Offset: -17 = Decrypted string: hZXgZishfj^ggZa
Offset: -18 = Decrypted string: gYWfYhrgei]ffY`
Offset: -19 = Decrypted string: fXVeXgqfdh\eeX_
Offset: -20 = Decrypted string: eWUdWfpecg[ddW^
Offset: -21 = Decrypted string: dVTcVeodbfZccV]
Offset: -22 = Decrypted string: cUSbUdncaeYbbU\
Offset: -23 = Decrypted string: bTRaTcmb`dXaaT[
Offset: -24 = Decrypted string: aSQ`Sbla_cW``SZ
Offset: -25 = Decrypted string: `RP_Rak`^bV__RY
Offset: -26 = Decrypted string: _QO^Q`j_]aU^^QX
我的输出:
Please enter string to decrypt: ff
Offset: -1 = Decrypted string: ff
Offset: -2 = Decrypted string: ff
Offset: -3 = Decrypted string: ff
Offset: -4 = Decrypted string: ff
Offset: -5 = Decrypted string: ff
Offset: -6 = Decrypted string: ff
Offset: -7 = Decrypted string: ff
Offset: -8 = Decrypted string: ff
Offset: -9 = Decrypted string: ff
Offset: -10 = Decrypted string: ff
Offset: -11 = Decrypted string: ff
Offset: -12 = Decrypted string: ff
Offset: -13 = Decrypted string: ff
Offset: -14 = Decrypted string: ff
Offset: -15 = Decrypted string: ff
Offset: -16 = Decrypted string: ff
Offset: -17 = Decrypted string: ff
Offset: -18 = Decrypted string: ff
Offset: -19 = Decrypted string: ff
Offset: -20 = Decrypted string: ff
Offset: -21 = Decrypted string: ff
Offset: -22 = Decrypted string: ff
Offset: -23 = Decrypted string: ff
Offset: -24 = Decrypted string: ff
Offset: -25 = Decrypted string: ff
Offset: -26 = Decrypted string: ff
我的代码(我把大部分程序都删掉了)
choice = 0
print ('*** Menu ***\n')
print ('1. Encrypt string')
print ('2. Decrypt string')
print ('3. Brute force decryption')
print ('4. Quit\n')
elif choice == 3:
print ('In command 3 - Brute force')
userString = input('\nPlease enter string to decrypt: ')
userList = list(userString)
offsetValue = 0
decryptIndex = 0
while offsetValue != -26 : # Once the count reaches -26 stop, hammer time
while decryptIndex < len(userList):
decryptChr = chr(ord(userList[decryptIndex]) + offsetValue)
userList[decryptIndex] = decryptChr
decryptIndex += 1
offsetValue -= 1
userString = ''.join(userList)
print ('Offset',offsetValue,' = Decrypted string:' ,userString)
print ('\n*** Menu ***\n')
print ('1. Encrypt string')
print ('2. Decrypt string')
print ('3. Brute force decryption')
print ('4. Quit\n')
choice = int(input('What would you like to do? [1,2,3,4]? '))
while choice != 1 and choice != 2 and choice != 3 and choice != 4:
choice = int(input('\nPlease re-enter either [1,2,3,4] '))
print ('\nGoodbye.')
有什么想法吗?!
答案 0 :(得分:2)
更容易使用str.translate
chars = "abcdefghijklmnopqrstuvwxyz"
rot1 = str.maketrans(chars, chars[1:]+chars[0])
message = input()
for i in chars:
print(message)
message = message.translate(rot1)
答案 1 :(得分:1)
在Python中解码凯撒密码的一种更简洁的方法是使用字符串切片。
取字母表,即:
src = 'abcdefghijklmnopqrstuvwxyz'
现在,对于每种可能性,使用shift n = 0, ..., 25
,我们可以为cypher构建一个新的字符集:
for n in range(26):
dest = src[n:] + src[:n]
然后,您可以通过查找源集和目标集中每个字符的位置来解码字符串s
:
decoded = ''.join(dest[src.index(c)] for c in s)
答案 2 :(得分:1)
原始程序的问题在于
行 offsetValue -= 1
不正确地缩进。
您不会重新初始化循环计数器,而且由于ord(userList[decryptIndex]) + offsetValue
是无效字符,您可能会导致chr抛出错误。
转换为列表并返回是笨拙且不必要的。使用字符串连接更清晰。虽然对于一个非常干净的解决方案,其他解决方案显示了解决这个问题的pythonic方法。
所以你的程序应该是:
choice = 0
print ('*** Menu ***\n')
print ('1. Encrypt string')
print ('2. Decrypt string')
print ('3. Brute force decryption')
print ('4. Quit\n')
elif choice == 3:
print ('In command 3 - Brute force')
userString = input('\nPlease enter string to decrypt: ')
offsetValue = 0
while offsetValue != -26 : # Once the count reaches -26 stop, hammer time
decryptIndex = 0
decryptedString = ""
while decryptIndex < len(userString):
c = ord(userString[decryptIndex]) + offsetValue
if c < 0: c += 128
decryptChr = chr(c)
decryptedString += decryptChr
decryptIndex += 1
offsetValue -= 1
print ('Offset',offsetValue,' = Decrypted string:' ,decryptedString)
print ('\n*** Menu ***\n')
print ('1. Encrypt string')
print ('2. Decrypt string')
print ('3. Brute force decryption')
print ('4. Quit\n')
choice = int(input('What would you like to do? [1,2,3,4]? '))
while choice != 1 and choice != 2 and choice != 3 and choice != 4:
choice = int(input('\nPlease re-enter either [1,2,3,4] '))
print ('\nGoodbye.')
答案 3 :(得分:1)
你可以按照以下方式做点什么:
from string import ascii_lowercase as alphabet
import string
def caesar(plaintext, shift):
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
table = string.maketrans(alphabet, shifted_alphabet)
return plaintext.translate(table)
plain='hello there'
shift=3
coded=caesar(plain,shift)
decoded=caesar(coded,-shift)
print plain
print coded
print decoded
打印:
hello there
khoor wkhuh
hello there
答案 4 :(得分:0)
我会从gnibbler那里无耻地偷走,因为他是迄今为止最好的答案。
我有点担心你的菜单处理。您打印出菜单,然后在选项内再次打印。也许这样一个“老派”的CLI菜单可以更优雅地处理。
我没有为gnibbler(肯定得到我的upvote)的实际答案做出贡献,但我试图解决另一个问题,这可能并希望可以帮助你获得“更好”的代码。
这是我的想法:
#! /usr/bin/python3.2
import sys
from collections import defaultdict
menu = '''
*** Menu ***
[1] Encrypt
[2] Decrypt
[3] Brute force
[4] Quit
'''
def caesar (s, offset):
chars = 'abcdefghijklmnopqrstuvwxyz'
return s.translate (str.maketrans (chars, chars [offset:] + chars [:offset] ) )
def decrypt ():
s = input ('Enter string to decrypt: ')
offset = int (input ('Enter offset: ') )
print (caesar (s, (-offset) % 26) )
def encrypt ():
s = input ('Enter string to encrypt: ')
offset = int (input ('Enter offset: ') )
print (caesar (s, offset) )
def bruteForce ():
s = input ('Enter string to brute force: ')
for offset in range (26):
print ('Offset {}:\t{}'.format (offset, caesar (s, (-offset) % 26) ) )
def unrecognized ():
print ('unrecognized command')
options = {'1': encrypt,
'2': decrypt,
'3': bruteForce,
'4': sys.exit}
options = defaultdict (lambda: unrecognized, options)
while ...: options [input (menu) ] ()
(inb4“奇怪的whitespacing”)