2013-07-19 25 views
3

您好,在此先感謝您的答案, 我試圖做第一個任務PythonChallenge: http://www.pythonchallenge.com/pc/def/map.html 和我有關於代碼的問題一個comuple。 我知道這個代碼的工作:凱撒的代碼 - 執行中的問題,在Python

import string 
letters = string.ascii_lowercase 
uletters = string.ascii_uppercase 
text = ("g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.") 
for x in range(0, 26): 
    text = text.replace(letters[x-2], uletters[x]) 
    print(text.lower()) 

我的代碼玩一點點,這裏是我的一點看法,而我有疑問: 1.當我運行:

text = text.replace(letters[x], uletters[x+2]) 

發生錯誤,例如「trynslyte」而不是「translate」。爲什麼這種轉變會做出這樣的改變? 2.當我改變: uletters = string.ascii_uppercase

uletters = string.ascii_lowercase 

一堆的 「Z」 S和 「y」 S現身。再次,這是怎麼回事?

非常感謝

回答

4

當評估letters[x-2]x是0或1,則結束與letters[-1]letters[-2],其在Python分別訪問的最後和倒數第二個的元素。這就是這一步工作的原因。但是,大於最後一個元素索引的索引並不具有相同的效果,因此當x太大時letters[x+2]將不起作用。

你需要做的是這樣的:

letters[(x+2)%len(letters)] 

要強制此環繞。

+0

另一種方法是製作'letters = string.ascii_lowercase * 2' – kindall

0

你必須處理環繞。如果x-2小於0,你會得到錯誤。

+0

不,這個方向沒問題。這是'x + 2'太大而導致問題的原因。 –

+0

你說得對。我注意到這是一個籠統的問題。 – Jiminion

1

更好的方法是使用str.translate()

from string import ascii_lowercase as lc 

text = ("g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. " 
     "bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. " 
     "sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.") 

print (text.translate(str.maketrans(lc, lc[2:] + lc[:2]))) 

要編寫一個編碼器,只是交換參數maketrans()各地:

print (text.translate(str.maketrans(lc[2:] + lc[:2], lc))) 
0

Wikipedia,凱撒密碼是這兩個數學全等:

E_n(x) ≡ (x + n) mod 26 
D_n(x) ≡ (x - n) mod 26 

哪裏E_n()是加密算法D_n(x)是解密算法,x是一個普通的算法,或密文,n是關鍵,而26是整數環的大小。因此,編寫一個程序來執行凱撒密碼的最簡單方法是......實現上述過程。

,你會用電腦做此獲得的唯一的併發症是你的整數0通過25操作不是事實,但在整數的兩個範圍,因爲你是從ASCII表解釋整數作爲字符。大寫字母是整數6590,小寫字母是整數97122

幸運的是,蟒蛇爲您提供了兩個函數ASCII字符轉換爲整數和背部:

>>> ord('a') 
97 
>>> chr(97) 
'a' 

你可以利用這個保留您的案件。我打算將ord作爲默認參數傳遞給參數,但是ASCII不會很快改變。但是,這可以讓你在不改變代碼的情況下加密不同的字符。

def E(x, n, m=26, upper_ord=ord('A'), lower_ord=ord('a')): 
    if x.isupper(): 
     return chr(((ord(x) - upper_ord + n) % m) + upper_ord) 
    else: 
     return chr(((ord(x) - lower_ord + n) % m) + upper_ord) 

def D(x, n, m=26, upper_ord=ord('A'), lower_ord=ord('a')): 
    return E(x, -n, m, upper_ord, lower_ord) 

>>> E('b', 3) 
'e' 
>>> E('b', 25) 
'a' 
>>> E('b', -3) 
'y' 
>>> E('e', -3) 
'b' 
>>> E('Q', 15) 
'F' 
>>> plaintext = "The quick brown fox jumps over the lazy dog" 
>>> ciphertext = " ".join(map(lambda w: "".join(E(x, 2) for x in w), (word for word in 
sentence.split()))) 
>>> ciphertext 
'Vjg swkem dtqyp hqz lworu qxgt vjg ncba fqi' 
>>> decrypted = " ".join(map(lambda w: "".join(D(x, 2) for x in w), (word for word in 
ciphertext.split()))) 
>>> decrypted 
'The quick brown fox jumps over the lazy dog' 

在我看來,使用子索引偏移是人爲設計的。數學公式是明確定義的,所以請使用它!