Python基礎練習(五):破譯密碼

題目描述

題目內容:

A國情報局抓獲敵國間諜一名,從間諜身上搜出了若干密電,在嚴刑逼供之下,間諜說出了密電加密方法:將明文電報(僅由大寫字母構成)中的所有字母均替換爲字母表中向後看的第n個字母,如果超過Z,則從A繼續數,這樣就得到了密文,比如ATTACK,向後看第2個字母,就加密爲CVVCFM。

可還沒等到間諜說出加密用的密鑰(數字n),就被臥底開槍打死,間諜臨死前在地板上畫了BYE三個字母。

情報局長看着一條條密電發了愁,但機智的你已經發現,原來間諜在告訴我們,所有密電的明文都以BYE結尾!

請編寫程序破譯這些密電吧!

輸入格式:

共一行字符串,全部由大寫字母構成的密文。

輸出格式:

共一行字符串,破譯後的明文。

輸入樣例1:

JNTQZCZF

輸出樣例1:

IMSPYBYE

時間限制:500ms內存限制:32000kb

解題思路

原始思路

  1. 所有密電明文均以BYE結尾,因此我們可以利用該條件獲知密鑰n。(通過密文的最後三位字母中的任意一個均可獲取,n即爲對應位置的字母編碼值的差值)
  2. 如果明文超過“Z”,則從“A”繼續數,這裏我們可以藉助其與26的差值得到。(英文字母總個數爲26)
  3. 將密文和明文分爲兩部分,最後三位和其他部分,分別計算即可
a = input().upper()
b = ""
n = ord('E')-ord(a[-1])
for i in a[:-3]:
    if ord(i)+n>ord("Z"):
        b += chr(ord(i)+n-26)
    else:
        b += chr(ord(i)+n)
b += "BYE"
print(b)

思路缺陷

在第一步中考慮不周,忽視了n的取值範圍。舉例說明,若a[-1]=“Z”,則n=-21,那麼當ord(i)=65,即i="a"時,chr的值就已不是任何一個大寫字母
在這裏插入圖片描述

思路改進

將n的取值分情況討論,計算出n的精確值

換種想法

對於具有週期性的數列,取餘數不失爲一種好方法

  1. 生成一個包含26個字母並且順序排列的列表,或可簡稱爲字母表(`・ω・´)
  2. 按照題目要求,先求出密鑰n
  3. 利用密鑰n求解密文移動後的位置,利用餘數求解明文( 劃重點 :由於此前已經生成新的字母表,範圍在在[0,25]內,所以此時利用生成後的位置數對26(字母個數)取餘極爲方便)

解題代碼

思路一

a = input().upper()
b = ""
if a[-1]<='E':
    n = ord('E')-ord(a[-1])
else:
    n = 26+(ord('E')-ord(a[-1]))
for i in a[:-3]:
    if ord(i)+n>ord("Z"):
        b += chr(ord(i)+n-26)
    else:
        b += chr(ord(i)+n)
b += "BYE"
print(b)

思路二

a = input().upper()
l = [chr(i) for i in range(ord("A"),ord("Z")+1)]
n = l.index('E')-l.index(s[-1])
b = ""
for i in a[:-3]:
        b += l[(l.index(i) + n)%26]
b += "BYE"
print(b)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章