Vigenère密码函数在Python中

时间:2016-12-10 21:05:23

标签: python function python-3.x encryption vigenere

在观看关于Vigenere Cipher的this tutorial之后,我(希望)了解它的基本概念。我们想要为字符串分配一个键,然后将字符串中的每个字母移动到键中每个字母的(从0开始)字母位置值。因此,当使用培根作为关键时,

Meet me in the park at eleven am
baco nb ac onb acon ba conbac on

变为

Negh zf av huf pcfx bt gzrwep oz

当我从头开始编写Vigenere Cipher时,我只知道第一步是将键分配给字符串。虽然我这样做,但我想知道每个字符是否都是alpha,以便我可以保留字符串中的任何特殊字符(!,@,#等),如果有的话。

text = input("Enter some text:")

def encrypt(text):

#key = bacon
encrypted = []
baconvalue = {'A':0, 'a':0, 'B':1, 'b':1, 'C':2, 'c':2, 'D':3, 'd':3, 'E':4, 'e':4, 'F':5, 'f':5, 'G':6, 'g':6, 'H':7, 'h':7, 'I':8, 'i':8, 'J':9, 'j':9, 'K':10, 'k':10, 'L':11, 'l':11, 'M':12, 'm':12, 'N': 13, 'n':13, 'O':14, 'o':14, 'P':15, 'p':15, 'Q':16, 'q':16, 'R':17, 'r':17, 'S':18, 's':18, 'T':19, 't':19, 'U':20, 'u':20, 'V':21, 'v':21, 'W':22, 'w':22, 'X':23, 'x':23, 'Y':24, 'y':24, 'Z':25, 'z':25 }


for letter in text:

#assign 'bacon' to text to get rotation value for each character
#preserve alpha characters

        if letter.isalpha():  

#character in string rotates x amount according to the corresponding value of char in bacon

            encrypted.append(letter, baconvalue)        

        else:    

            encrypted.append(letter)            

        return ''.join(encrypted)

print(encrypt(text,))

但是正如你所看到的,我不知道从哪里开始,如何将培根分配给字符串。我至少走在正确的轨道上吗?如果可以的话请帮忙。谢谢。

3 个答案:

答案 0 :(得分:3)

使用用户输入的值作为键索引字符串的方法是创建变量starting_index并将其设置为= 0。这样,迭代将从字符串中的第一个字符开始,您将能够使用之前创建的rotation字典生成alphabet_pos值。

使用您的rotate功能通过您创建的新旋转变量旋转字母。如果在您的字典中找到该字母,encrypt函数将附加此新字母并继续,直到您达到该键中的最后一个索引值。然后它将加密的字母连接在一起。

alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1, 'C':2, 'c':2, 'D':3, 'd':3,
'E':4, 'e':4, 'F':5, 'f':5, 'G':6, 'g':6, 'H':7, 'h':7, 'I':8, 'i':8,
'J':9, 'j':9, 'K':10, 'k':10, 'L':11, 'l':11, 'M':12, 'm':12, 'N': 13,
'n':13, 'O':14, 'o':14, 'P':15, 'p':15, 'Q':16, 'q':16, 'R':17, 'r':17,
'S':18, 's':18, 'T':19, 't':19, 'U':20, 'u':20, 'V':21, 'v':21, 'W':22,
'w':22, 'X':23, 'x':23, 'Y':24, 'y':24, 'Z':25, 'z':25 }

def alphabet_position(letter):
    alphabet_pos = {'A':0, 'a':0, 'B':1, 'b':1, 'C':2, 'c':2, 'D':3,
'd':3, 'E':4, 'e':4, 'F':5, 'f':5, 'G':6, 'g':6, 'H':7, 'h':7, 'I':8,
'i':8, 'J':9, 'j':9, 'K':10, 'k':10, 'L':11, 'l':11, 'M':12, 'm':12,
'N': 13, 'n':13, 'O':14, 'o':14, 'P':15, 'p':15, 'Q':16, 'q':16,
'R':17, 'r':17, 'S':18, 's':18, 'T':19, 't':19, 'U':20, 'u':20, 'V':21,
'v':21, 'W':22, 'w':22, 'X':23, 'x':23, 'Y':24, 'y':24, 'Z':25, 'z':25
}
    pos = alphabet_pos[letter]
    return pos

def rotate(letter, rot):
    shift = 97 if letter.islower() else 65
    return chr((ord(letter) + rot - shift) % 26 + shift)

def encrypt(text, key):
    encrypted = []    
    starting_index = 0
    for letter in text:
    # if it's alphanumerical, keep it that way
    # find alphabet position
        rotation = alphabet_position(key[starting_index])
    # if it's a space or non-alphabetical character, append and move on
        if not letter in alphabet_pos:
            encrypted.append(letter)
        elif letter.isalpha():            
            encrypted.append(rotate(letter, rotation))             

    #if we've reached last index, reset to zero, otherwise + by 1
        if starting_index == (len(key) - 1): 
            starting_index = 0
        else: 
            starting_index += 1

    return ''.join(encrypted)    

text = input("Enter some text:")
key = input("Enter a key:")

print(encrypt(text,key))

答案 1 :(得分:1)

所以我的代码很长,但是效果很好。希望对您有帮助

def VigenereCiphre(line, key):
    isupper = True
    key = key.strip(' ')
    key = key.upper()
    k = list(key)
    print(k)
    returnLine = []
    i = 0
    for char in list(line):

        # Check if current character is symbol. If true append it to encrypted line
        if ord(char) < 65 or ord(char) > 122:
            returnLine.append(char)
        elif ord(char) > 90 and ord(char) < 97:
            returnLine.append(char)
        else:
            # Checks if letter is capital. If it's not, stores isupper to false and make it uppercase
            if ord(char) > 90:
                isupper = False
                char = char.upper()

            else:
                isupper = True

            # Checks if key's index isn't out of range, if it is, set it back to 0
            print(isupper)
            if i == len(k):
                i = 0

            # create new character based on it's value

            c = ord(char) + ord(k[i]) - 65
            if c > 90:
                c = c - 25

            if isupper == False:
                print(c)
                c = c + 32
                print(c)

            returnLine.append(chr(c))

            i += 1

    a = ''
    return a.join(returnLine)

答案 2 :(得分:0)

可能我的解密Vigenère密码的完整实现可能会帮助您和其他人(它使用具有自动关联的Friedman测试方法)理解该方法。

您可以在此处找到代码:https://github.com/ferreirafabio/vigenere-py