Vigenère Cipher 函数实现
Vigenère Cipher function implementation
看完 this tutorial Vigenere Cipher 之后,我(希望)了解它的基本概念。我们想为字符串分配一个键,然后将字符串中的每个字母移动键中每个字母的(基于 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,))
但是如您所见,就如何将 bacon 分配给字符串而言,我不知道从哪里开始。我至少在正确的轨道上吗?
使用用户输入的值作为键索引字符串的方法是创建一个变量 starting_index
并将其设置为 = 0
。这样,迭代将从字符串中的第一个字符开始,您将能够使用之前创建的 alphabet_pos
字典生成 rotation
值。
使用您的 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))
我破译 Vigenère 密码的完整实现可能会帮助您和其他人(它使用具有自相关性的 Friedman 测试方法)理解该方法。
您可以在此处找到代码:https://github.com/ferreirafabio/vigenere-py
所以我的代码很长,但效果很好。希望对你有帮助
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)
# Without import libraries
# Keep it simple
alph = 'abcdefghijklmnopqrstuvwxyz'
def encrypt_letter(char, key):
if char.isalpha():
shift = alph.index(char)
shifted_alph = alph[shift:] + alph[:shift] # rotate
result = shifted_alph[key]
else:
result = char
return result
def calculate_shifts(letter):
return alph.index(letter)
def encrypt_text(txt, keyword):
txt = txt.lower()
en_ls = list()
# # >>> Method 1 for padding
# keyword_times_in_txt = (int(len(txt) / len(keyword))+1) # round up
# txt_padding_with_keyword = (keyword * keyword_times_in_txt)
# txt_padding_with_keyword = txt_padding_with_keyword[:len(txt)] # slice at length of txt
# # <<< Method 1 for padding
# >>> Method 2 for padding
txt_padding_with_keyword = list()
for i in range(len(txt)):
len_keyword = len(keyword)
txt_padding_with_keyword.append(keyword[i % len_keyword])
# <<< Method 2 for padding
for i in range(len(txt)):
key = calculate_shifts(txt_padding_with_keyword[i])
char = txt[i]
en_letter = encrypt_letter(char, key)
en_ls.append(en_letter)
result = "".join(en_ls)
print(f"Keyword : {keyword}")
print(f"Text : {txt}")
print(f"Padded text with keyword: {''.join(txt_padding_with_keyword)}")
return result
# in_txt = input("Which text should be encrypted?")
# in_keyword = input("Which keyword should be used?")
in_txt = "Python is Really Beautiful!"
in_keyword = "Random"
in_txt = in_txt.lower()
in_keyword = in_keyword.lower()
print(f"Encrypted text : {encrypt_text(in_txt, in_keyword)}")
# Output:
# Keyword : random
# Text : python is really beautiful!
# Padded text with keyword: randomrandomrandomrandomran
# Encrypted text : gygkcz if fqrlyb nvahwwrll!
看完 this tutorial Vigenere Cipher 之后,我(希望)了解它的基本概念。我们想为字符串分配一个键,然后将字符串中的每个字母移动键中每个字母的(基于 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,))
但是如您所见,就如何将 bacon 分配给字符串而言,我不知道从哪里开始。我至少在正确的轨道上吗?
使用用户输入的值作为键索引字符串的方法是创建一个变量 starting_index
并将其设置为 = 0
。这样,迭代将从字符串中的第一个字符开始,您将能够使用之前创建的 alphabet_pos
字典生成 rotation
值。
使用您的 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))
我破译 Vigenère 密码的完整实现可能会帮助您和其他人(它使用具有自相关性的 Friedman 测试方法)理解该方法。
您可以在此处找到代码:https://github.com/ferreirafabio/vigenere-py
所以我的代码很长,但效果很好。希望对你有帮助
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)
# Without import libraries
# Keep it simple
alph = 'abcdefghijklmnopqrstuvwxyz'
def encrypt_letter(char, key):
if char.isalpha():
shift = alph.index(char)
shifted_alph = alph[shift:] + alph[:shift] # rotate
result = shifted_alph[key]
else:
result = char
return result
def calculate_shifts(letter):
return alph.index(letter)
def encrypt_text(txt, keyword):
txt = txt.lower()
en_ls = list()
# # >>> Method 1 for padding
# keyword_times_in_txt = (int(len(txt) / len(keyword))+1) # round up
# txt_padding_with_keyword = (keyword * keyword_times_in_txt)
# txt_padding_with_keyword = txt_padding_with_keyword[:len(txt)] # slice at length of txt
# # <<< Method 1 for padding
# >>> Method 2 for padding
txt_padding_with_keyword = list()
for i in range(len(txt)):
len_keyword = len(keyword)
txt_padding_with_keyword.append(keyword[i % len_keyword])
# <<< Method 2 for padding
for i in range(len(txt)):
key = calculate_shifts(txt_padding_with_keyword[i])
char = txt[i]
en_letter = encrypt_letter(char, key)
en_ls.append(en_letter)
result = "".join(en_ls)
print(f"Keyword : {keyword}")
print(f"Text : {txt}")
print(f"Padded text with keyword: {''.join(txt_padding_with_keyword)}")
return result
# in_txt = input("Which text should be encrypted?")
# in_keyword = input("Which keyword should be used?")
in_txt = "Python is Really Beautiful!"
in_keyword = "Random"
in_txt = in_txt.lower()
in_keyword = in_keyword.lower()
print(f"Encrypted text : {encrypt_text(in_txt, in_keyword)}")
# Output:
# Keyword : random
# Text : python is really beautiful!
# Padded text with keyword: randomrandomrandomrandomran
# Encrypted text : gygkcz if fqrlyb nvahwwrll!