2017-10-21 67 views
0

我得到的錯誤字符串索引超出範圍內的加密函數我不知道如何得到腐爛重複文本。該代碼僅在兩個輸入具有相同長度時才起作用。如果可以,我想讓alphabet_position和rotate_character功能保持一致。我的vigenere密碼加密函數有什麼問題?

alpha_lower_list = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", 
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] 
alpha_upper_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", 
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] 

def alphabet_position(letter):  
    if letter in alpha_upper_list: 
     return alpha_upper_list.index(letter) 
    else: 
     return alpha_lower_list.index(letter) 

def rotate_character(char, rot): 
    rotated_letter = '' 
    if char.isalpha(): 
     rotate = alphabet_position(char) + rot 
     if rotate < 26: 
      if char in alpha_upper_list: 
       rotated_letter = alpha_upper_list[rotate] 
       return(rotated_letter) 
      else: 
       rotated_letter = alpha_lower_list[rotate] 
       return(rotated_letter) 
     else: 
      if char in alpha_upper_list: 
       rotated_letter = alpha_upper_list[rotate % 26] 
       return(rotated_letter) 
      else: 
       rotated_letter = alpha_lower_list[rotate % 26] 
       return(rotated_letter) 
    else: 
     return(char) 

def encrypt(text, rot): 
    lis = [] 
    for i in range(len(text)): 
     lis.append(rotate_character(text[i], alphabet_position(rot[i]))) 

    return (''.join(lis)) 

def main(): 
    user_text = input("Type a message: ") 
    rotate_by = input("Rotate by: ") 

    print(encrypt(user_text, rotate_by)) 

if __name__ == '__main__': 
    main() 

回答

0

你在你的程序的第36行使用迭代中rot[i]走出界外 - i將上升到您的明文的長度,可以比的關鍵更大。

嘗試通過密鑰的長度做一個模塊DIV,這樣你應該環繞很好的關鍵:你仍然不滿意你的腳本返回的結果

lis.append(rotate_character(text[i], alphabet_position(rot[i % len(rot)])))

編輯,所以我挖得更深一點。潛在的問題是,你試圖實現Vigenere的一些在線工具叫做「增強模式」:既不是純文本文件,也不是密文文件,它們可能來自[a-zA-Z],但可能是「特殊字符」。從[0-9]元素或字符,如<space><

如果您的腳本遇到一個特殊字符,它不會旋轉,而是複製過來,不被作爲else分枝的rotate_character完成的;這是對的。然而,在encrypt()中,您將消耗我們稱之爲「keysymbol」的,每符號表示您遇到的明文。這意味着,實際上,您正在「浪費」明文符號上的密鑰符號,該符號在所有都不會被加密(vulgo旋轉)。

一旦你意識到這一點,修復就變得很明顯:當我們遇到一個特殊字符時,將它複製到輸出列表中,但是不要推進密鑰流。如果我們實際需要使用密鑰符號,則密鑰流只應該先進。

翻譯成代碼:

def encrypt(text, rot): 
    lis = [] 
    keystream = 0 
    for i in range(len(text)): 
     keychar = keystream % len(rot) 
     if text[i].isalpha(): 
      lis.append(rotate_character(text[i], alphabet_position(rot[keychar]))) 
      keystream += 1 
     else: 
      lis.append(text[i]) 

    return (''.join(lis)) 
+0

謝謝你,我只需要弄清楚如何返回此: 'Feqwgba <3 fnvta effo ox0xiv syfvbxf' insted的 'Feqwgba <3 asgdm zuvc zf0xka plppiey' 的 – shiquann

+0

能您請提供明文和密鑰,在該密碼下加密是有效的輸出?這將緩解跟蹤bug ... –

+0

這是輸入vigenere.encrypt('航行<3通過br0ken港口','NeilYoung') – shiquann