使用凯撒密码解密文件
我想解密一个加密的文件。但是在最后一步,也就是把它转换成可以比较的形式时,我遇到了麻烦。这个比较是跟一个装满单词的字典进行的。有没有人能给我一些指导?我在比较这两个东西时感到很困难。
#this function takes a string and encrypts ONLY letters by k shifts
def CaeserCipher(string, k):
#setting up variables to move through
upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'*10000
lower = 'abcdefghijklmnopqrstuvwxyz'*10000
newCipher = ''
#looping each letter and moving it k times
for letter in string:
if letter in upper:
if upper.index(letter) + k > 25:
indexPosition = (upper.index(letter) + k)
newCipher = newCipher + upper[indexPosition]
else:
indexPosition = upper.index(letter) + k
newCipher = newCipher + upper[indexPosition]
elif letter in lower:
if lower.index(letter) + k > 25:
indexPosition = (lower.index(letter) + k)
newCipher = newCipher + lower[indexPosition]
else:
indexPosition = lower.index(letter) + k
newCipher = newCipher + lower[indexPosition]
else:
newCipher = newCipher + letter
return newCipher
f = open('dictionary.txt', "r")
dictionary = set()
for line in f:
word = line.strip()
dictionary.add(word)
print dictionary
#main file
#reading file and encrypting text
f = open('encryptMystery1.txt')
string = ''
out = open("plain1.txt", "w")
myList = []
for line in f:
myList.append(line)
for sentence in myList:
for k in range(26):
updatedSentence = CaeserCipher(sentence, k)
for word in updatedSentence.split():
if word in dictionary:
out.write(updatedSentence)
break
print myList
f.close()
out.close()
1 个回答
2
让我们一步一步来,第一步是
为什么你在凯撒密码中有260,000个字符的长字符串
抱歉,我不是想夸大其词,但你知道这样会占用比,嗯,空间还要多的地方,对吧?而且这是完全不必要的。这是一种丑陋又慢的解决办法,只是为了避免理解%
(取模)运算符。别这么做。
现在,来讲讲取模:
第二步当然是理解取模。其实这并不难,就像是除法问题的余数。你还记得上学时刚学除法的样子吗?7/4
是1r3
而不是1.75
,对吧?在Python中有相关的函数。7/4 == 1.75
,7//4 == 1
,而7 % 4 == 3
。这很有用,因为它可以让一个数字在固定长度内“循环”。
比如说,你有一个包含26个索引的字符串(就像,我不知道,字母表?)。你想在一个起始索引上加一个数字,然后返回结果,但天哪,你在Y
上加2却不行!好吧,使用取模就可以。Y
在索引24(记住,索引是从0开始的),24+2是26,但没有第26个索引。然而,如果你知道你的字符串只有26个元素,我们可以用取模来解决这个问题。
按照这个逻辑,index + CONSTANT % len(alphabet)
将始终用简单的数学返回正确的数字,而不是你刚刚搞砸的那条25万元素的长字符串。
唉,你妈妈会为你感到羞愧。
反转凯撒密码
所以你有个好主意,逐行处理每一行并应用各种密码。如果我是你,我会把它们都放到不同的文件里,甚至放到不同的列表元素中。不过要记住,如果你要反转密码,你需要用-k
而不是k
。其实最好是直接修改你的凯撒密码来检测这一点,因为在这种情况下取模的技巧是行不通的。试试这样的代码:
def cipher(text, k):
cipherkey = "SOMESTRINGGOESHERE"
if k < 0:
k = len(cipherkey) + k
# len(cipherkey) - abs(k) would be more clear, but if it HAS to be
# a negative number to get in here, it seems silly to add the call
# to abs
然后你可以这样做:
startingtext = "Encrypted_text_goes_here"
possibledecrypts = [cipher(startingtext, -i) for i in range(1,26)]