[英]Python text encryption: rot13
我目前正在執行一項任務,該任務使用rot 13加密文本,但是我的某些文本不會注冊。
# cgi is to escape html
# import cgi
def rot13(s):
#string encrypted
scrypt=''
alph='abcdefghijklmonpqrstuvwxyz'
for c in s:
# check if char is in alphabet
if c.lower() in alph:
#find c in alph and return its place
i = alph.find(c.lower())
#encrypt char = c incremented by 13
ccrypt = alph[ i+13 : i+14 ]
#add encrypted char to string
if c==c.lower():
scrypt+=ccrypt
if c==c.upper():
scrypt+=ccrypt.upper()
#dont encrypt special chars or spaces
else:
scrypt+=c
return scrypt
# return cgi.escape(scrypt, quote = True)
given_string = 'Rot13 Test'
print rot13(given_string)
13 r
[Finished in 0.0s]
嗯,似乎一堆東西都沒有用。 主要問題應該在ccrypt = alph[ i+13 : i+14 ]
:您缺少% len(alph)
否則,例如,如果i
等於18
,那么您將超出列表邊界。 實際上,在您的輸出中,只有e
編碼為r
因為它是測試字符串中唯一一個字母,該字母移動13不會超出邊界。
該答案的其余部分只是一些清潔代碼的提示:
alph='abc..
你可以申報import string
在腳本的開頭和使用string.lowercase
string[i]
來完成工作 if c.isupper() ...
可以使用內置函數來代替c == c.upper()
。 您遇到的麻煩是切片問題。 如果您的字符位於字母的后半部分,則該字符為空,因為i+13
不在結尾。 有幾種方法可以修復它。
最簡單的方法是簡單地將您的字母字符串加倍(字面意思是: alph = alph * 2
)。 這意味着您最多可以訪問52個值,而不是最多26個值。不過,這是一個很粗糙的解決方案,最好只修復索引。
更好的選擇是從索引中減去13,而不是加13。Rot13是對稱的,因此兩者具有相同的效果,並且將起作用,因為負索引在Python中是合法的(它們指的是從末尾開始倒數的位置) )。
無論哪種情況,實際上都沒有必要做任何切片。 您可以簡單地獲取一個值(與C不同,Python中沒有char
類型,因此單個字符也是字符串)。 如果僅進行此更改,則可能會弄清楚為什么當前代碼失敗,因為嘗試從字符串末尾訪問單個值將引發異常。
編輯:實際上,在考慮了哪種解決方案真正是最好的之后,我傾向於建議完全避免使用基於索引算法的解決方案。 更好的方法是使用Python出色的字典來完成從原始字符到加密字符的映射。 您可以像這樣構建和使用Rot13詞典:
alph="abcdefghijklmnopqrstuvwxyz"
rot13_table = dict(zip(alph, alph[13:]+alph[:13])) # lowercase character mappings
rot13_table.update((c.upper(),rot13_table[c].upper()) for c in alph) # upppercase
def rot13(s):
return "".join(rot13_table.get(c, c) for c in s) # non-letters are ignored
這條線
ccrypt = alph[ i+13 : i+14 ]
不會執行您認為的操作-它從i+13
到i+14
返回一個字符串切片,但是如果這些索引大於字符串的長度,則該切片將為空:
"abc"[5:6] #returns ''
這意味着您的解決方案將從n
開始的所有內容轉換為空字符串,從而產生觀察到的輸出。
正確的實現方式是(1.)使用模運算將索引約束為有效數字,以及(2.)使用簡單字符訪問而不是字符串切片,這更易於閱讀,更快並且拋出IndexError
對於無效的索引,這意味着您的錯誤將很明顯。
ccrypt = alph[(i+13) % 26]
可能引起一些問題的第一件事-字符串列表的n
和o
切換,因此您需要進行調整:)至於算法,在運行時:
ccrypt = alph[ i+13 : i+14 ]
想一想當您從第一次迭代中得到25
時(對於z
)會發生什么。 現在,您正在尋找索引位置alph[38:39]
(旁注:您實際上可以說alph[38]
),它遠遠超出了26個字符的字符串的界限,該字符串將返回''
:
In [1]: s = 'abcde'
In [2]: s[2]
Out[2]: 'c'
In [3]: s[2:3]
Out[3]: 'c'
In [4]: s[49:50]
Out[4]: ''
至於解決方法,有許多有趣的方法。 您的代碼只需進行一些修改即可正常運行。 您可以做的一件事是創建已經“旋轉” 13個位置的字符映射:
alph = 'abcdefghijklmnopqrstuvwxyz'
coded = 'nopqrstuvwxyzabcdefghijklm'
我們在這里所做的全部工作是將原始列表分成13個一半,然后交換它們-現在我們知道,如果我們采用a這樣a
字母並獲得其位置( 0
),則編碼列表中的相同位置將是rot13
值。 因為這是一項任務,所以我不會詳細說明如何執行任務,但是請查看它是否使您步入正軌(@Makoto的建議是檢查結果的理想方法)。
如果您將其作為Python課程的練習,請忽略此內容,只是說...
>>> import codecs
>>> codecs.encode('Some text', 'rot13')
'Fbzr grkg'
>>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.