[写完之后,我意识到我正在替换已经部分解密的消息,所以我似乎已经找到了错误,但是现在我似乎无法弄清楚如何用一个字母一个字母地替换字母使用一堆if-else语句,看起来效率很低。有什么建议吗?]
加密邮件的一部分
THEXMUNITIONSXFACTORYXREPORTEDXDAMAGEDXINXBOMBINGXRAIDXSTOPXKEEPXLOWXPROFILEXSTOPXURGENTXMESSAGESXCOMPROMISEDXSWITCHXTOXENCRYPTEDXURGENTXSTOPASJHXBLDZBLVZJXWZBHDFFVMYHSJYDMBJDOSUBGJDKBFSPWBHDMJSHJBAYJXBSRWMJBDZSMRWBGJDKBSNDYOBJXWBDJXWZBHDMJSHJBSJBSIIBHDGJGBGJDKBSHJYNSJWBDKWZSJYDMBEIVWBGKDDMBGJDKBZWKDZJBDMBJXWBKDIYHWBGJSJYDMBGJDKBSHJYNSJWBDKWZSJYDMBMDZJXADDOGBGJDKBZWKDZJBDMBUDVZBGJSJVGBGJDKBSBESJJIWGXYKBGWWMBOWKSZJYMRBLZDFBOWWKBXSZEDVZBGJDKBMWBJBFWWJYMRBSJBCICCBTVIVBJDMYRXJBJXWBKSZPBVMOWZBJXWBDSPBGJDKBPWWKBIDABKZDLYIWBGJDKBOYGZWRSZOBISGJBFWGGSRWBGJDKBYMNWGJYRSJWBZVFDVZGBDLBGJZYPWGBGJDKBPWWKBIDABKZDLYIWBGJDKBVMPMDAMBNWGGWIBYGBODHPWOBSJBOWWKBXSZEDVZBGJDKBJXWBODRBJZSYMWZBFSUBEWBODVEIWBSRWMJBWBWZHYGWBHSVJYDMBGJDKBDKWZSJYDMBMDZ
我需要通过密钥替换来解密消息。根据每个字母在以前未加密的邮件中出现的频率,给了我一个有序的字符串,然后我被告知解密所需要做的就是将加密文本中最频繁的字母替换为过去的非加密文本等等。
我还被告知忽略前141个字符,因为它们已经被解密。
从上面的代码中可以看到,我做了以下事情:
从第142个字符开始复制加密的字符串,以仅处理仍加密的位
使用字母和它们在消息中出现的次数创建字典
将该字典转换为列表,然后按降序排序
最后,我遍历“频率字符串”(本质上是给我的密钥,指示未加密消息中的字母出现的频率)并将其与消息中的字母按频率排序清单。并使用replace()字符串方法替换它们
已加密=消息[142:] frequencyString =“ XTOEASRINPDCLHUMGBFYWVKZJQ” print(orderedChars)#用于调试目的
def counter(chars):
d = {}
for char in message:
d[char] = d.get(char,0) + 1
return d
charCount = counter(message)
def sortChars(charCount):
orderedChars = []
for k in charCount:
orderedChars.append([charCount[k],k])
orderedChars = sorted(orderedChars, reverse=True)
return orderedChars
orderedChars = sortChars(charCount)
def charMatch(orderedChars, frequencyString):
global encrypted
i=-1
for char in frequencyString:
i+=1
print(orderedChars[i][1]+"->"+char,end=" $ ") #for debuging purposes
encrypted = encrypted.replace(orderedChars[i][1],char)
encrypted = encrypted.replace("X"," ")
print()
print()#for debuging purposes
print(encrypted) #for debuging purposes
return encrypted
print()
charMatch(orderedChars,frequencyString)
输出
[[1449,'B'],[830,'J'],[784,'D'],[748,'W'],[578,'S'],[530,'G' ],[469,'Z'],[413,'Y'],[403,'M'],[343,'K'],[251,'O'],[233,'X'], [232,'H'],[229,'I'],[191,'V'],[190,'F'],[145,'E'],[142,'R'],[111 ,'L'],[95,'U'],[86,'A'],[77,'N'],[70,'P'],[22,'T'],[11,' C'],[6,'Q']]
B-> X $ J-> T $ D-> O $ W-> E $ S-> A $ G-> S $ Z-> R $ Y-> I $ M-> N $ K- > P $ O-> D $ X-> C $ H-> L $ I-> H $ V-> U $ F-> M $ E-> G $ R-> B $ L-> F $ U- > Y $ A-> W $ N-> V $ P-> K $ T-> Z $ C-> J $ Q-> Q $
WZFJJFDBJFYBZJGBJFDMMYVHFWZHDVJZDDWYJSZDKJMWKGJFDVZWFZJWHZJJWBGVZJDBWVBGJSZDKJWVDHDJZJGJDZJGBJFDVZWFZJWZJWHHJFDSZSJSZDKJWFZHVWZGJDKGBWZHDVJGHYGJSKDDVJSZDKJBGKDBZJDVJZJGJKDHHFGJSZWZHDVJSZDKJWFZHVWZGJDKGBWZHDVJVDBZJWDDDSJSZDKJBGKDBZJDVJYDYBJSZWZYSJSZDKJWJGWZZHGSJHKJSGGVJDGKWBZHVBJFBDMJDGGKJJWBGDYBJSZDKJVGJZJMGGZHVBJWZJJHJJJZYHYJZDVHBJZJZJGJKWBKJYVDGBJZJGJDWKJSZDKJKGGKJHDWJKBDFHHGJSZDKJDHSBGBWBDJHWSZJMGSSWBGJSZDKJHVVGSZHBWZGJBYMDYBSJDFJSZBHKGSJSZDKJKGGKJHDWJKBDFHHGJSZDKJYVKVDWVJVGSSGHJHSJDDFKGDJWZJDGGKJJWBGDYBJSZDKJZJGJDDBJZBWHVGBJMWYJGGJDDYGHGJWBGVZJGJGBFHSGJFWYZHDVJSZDKJDKGBWZHDVJVDBZJWDDDSJJWSJGGGVJSYFFGSSFYHJSZDKJVGJZJMGGZHVBJWZJKBJJJZYHYJZDMDBBDWJWZJZJGJDHDJHHDVJSZDKJDDJVDZJMWKGJFDVZWFZJYVZHHJZJGJYSYWHJDWYJSZDKJDDJVDZJMWKGJ
答案 0 :(得分:0)
您已使用大多数代码来查找字符频率。您提到您发现执行就地替换不起作用。因此,您需要创建一个单独的缓冲区来存储解密的消息。我发现创建两个频率字符串的映射更加容易:
# Your other code....
# orderedChars needs to be converted to string like frequencyString...
# Zip the 2 frequency strings to a dictionary
letterMap = dict(zip(orderedChars, frequencyString))
# Create an empty array to hold decrypted msg
decrypted = [''] * len(encrypted)
# Decrypt the message letter by letter
for i,c in enumerate(encrypted):
decrypted[i] = letterMap[c]
# Convert to string and print
print(''.join(decrypted).replace('X', ' '))
如评论中所述,您也可以使用translate
进行此操作。
# Build the translation table
translationTable = str.maketrans(orderedChars, frequencyString)
# Decrypt and print
print(encrypted.translate(translationTable).replace('X', ' '))
两个代码产生相同的输出。