使用凯撒密码解密文件

0 投票
1 回答
844 浏览
提问于 2025-04-18 03:19

我想解密一个加密的文件。但是在最后一步,也就是把它转换成可以比较的形式时,我遇到了麻烦。这个比较是跟一个装满单词的字典进行的。有没有人能给我一些指导?我在比较这两个东西时感到很困难。

#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/41r3而不是1.75,对吧?在Python中有相关的函数。7/4 == 1.757//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)]

撰写回答