使用 Python 的随机 Vigenere 密码
Randomized Vigenere Cipher with Python
开始前澄清一下:我知道有类似的主题,但没有任何内容真正提供任何直接帮助。另外:这是一个 class 项目;所以我不想找任何人为我编写项目代码。提示和建议是我正在寻找的。 (我会为了这种事去找我的教授,但他懒得查他的电子邮件。)
该程序旨在获取用户提供的种子,根据整数生成密钥,然后生成一个 95 x 95 矩阵,其中所有可打印的 ascii 字符都可用于 encryption/decryption 目的。 (键全是 alpha,并且大写)
关键:所有单元格都必须随机化。见下图:
Randomized Vigenere Matrix
下面我会post我的代码(Python当然不是我的强项,尽管我一定会接受建设性的批评。):
import random
class Vigenere(object):
def __init__(self, seed):
random.seed(seed)
#string containing all valid characters
self.symbols= """!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abcdefghijklmnopqrstuvwxyz{|}~"""
self.eTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.dTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.keyWord = ""
self.message = ""
self.ciphertext = ""
self.keywordFromSeed(seed)
def setMessage(self,message):
self.message = message
#Generate psuedorandom keyword from seed
def keywordFromSeed(self,seed):
Letters = []
while seed > 0:
Letters.insert(0,chr((seed % 100) % 26 + 65))
seed = seed // 100
self.keyWord = "".join(Letters)
self.buildVigenere()
#Contructs a 95 x 95 matrix filled randomly
def buildVigenere(self):
n = len(self.symbols)
#Build the vigenere matrix
for i in range(n):
temp = self.symbols
for j in range(n):
r = random.randrange(len(temp))
self.eTable[i][j] = temp[r]
#This line below does not fill entire matrix. Why?
self.dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
def encrypt(self):
for i in range(len(self.message)):
mi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.eRetrieve(ki,mi)
def decrypt(self):
for i in range(len(self.message)):
emi = i
ki = i % len(self.keyWord)
char = self.dRetrieve(ki,emi)
self.ciphertext = self.ciphertext + char
print(self.ciphertext)
def eRetrieve(self,ki,mi):
row = ord(self.message[mi]) - 32
col = ord(self.keyWord[ki]) - 32
print(row, col)
return self.eTable[row][col]
def dRetrieve(self,ki,emi):
n = len(self.symbols)
whichRow = ord(self.keyWord[ki]) - 32
whichCol = ord(self.message[emi]) - 32
return(self.dTable[whichRow][whichCol])
为了以防万一,这是我的 main.py:
import argparse
import randomized_vigenere as rv
def main():
#Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", dest="mode", default = "encrypt", help="Encrypt or Decrypt")
parser.add_argument("-i", "--inputfile", dest="inputFile", default = "inputFile.txt", help="Input Name")
parser.add_argument("-o", "--outputfile", dest="outputFile", default = "outputFile.txt", help="Output Name")
parser.add_argument("-s", "--seed", dest="seed", default =7487383487438734, help="Integer seed")
args = parser.parse_args()
#Set seed and generate keyword
seed = args.seed
#Construct Matrix
f = open(args.inputFile,'r')
message = f.read()
Matrix = rv.Vigenere(seed)
Matrix.setMessage(message)
if(args.mode == 'encrypt'):
Matrix.encrypt()
Matrix.setMessage(Matrix.ciphertext)
Matrix.decrypt()
else:
Matrix.decrypt()
o = open(args.outputFile,'w')
o.write(str(Matrix.ciphertext))
if __name__ == '__main__':
main()
我一直在使用默认种子:7487383487438734
我的明文:ABCdefXYZ
我要回答这个问题:
#This line below does not fill entire matrix. Why?
我认为这是你当前的问题。如果我没记错的话,这应该是你问题的第一行,而不是函数中的简单注释:
def buildVigenere(self):
n = len(self.symbols)
#Build the vigenere matrix
for i in range(n):
temp = self.symbols
for j in range(n):
r = random.randrange(len(temp))
self.eTable[i][j] = temp[r]
#This line below does not fill entire matrix. Why?
self.dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
我做的第一件事是构建一个独立的小示例,如下所示:
import random
def buildVigenere():
symbols= """!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abcdefghijklmnopqrstuvwxyz{|}~"""
n = len(symbols)
eTable = [[0 for i in range(len(symbols))] for i in range(len(symbols))]
dTable = [[0 for i in range(len(symbols))] for i in range(len(symbols))]
#Build the vigenere matrix
for i in range(n):
temp = symbols
for j in range(n):
r = random.randrange(len(temp))
eTable[i][j] = temp[r]
print (r, len(temp), j, len(symbols), temp[r])
#This line below does not fill entire matrix. Why?
print (ord(temp[r])-32)
dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
print dTable
buildVigenere()
如果你想在这里找到答案,你真的应该学会这样做,更普遍的是成为一名成功的程序员。找到问题所在,并能在简单的案例中重现,往往是关键。
这里我得到一个错误:
Exception "unhandled IndexError"
list assignment index out of range
我添加了一些打印语句(见上文),我发现错误来自 symbols
字符串中缺少 < > =
。
你为什么不使用 chr
来构建你的字符串 symbols
?
对于 buildVigenere
,您可以使用
random.shuffle(x)
我能够让它工作。我将 post 我的实现如下:
main.py
import argparse
import randomized_vigenere as rv
def main():
#Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", dest="mode", default = "encrypt", help="Encrypt or Decrypt")
parser.add_argument("-i", "--inputfile", dest="inputFile", default = "inputFile.txt", help="Input Name")
parser.add_argument("-o", "--outputfile", dest="outputFile", default = "outputFile.txt", help="Output Name")
parser.add_argument("-s", "--seed", dest="seed", default =7487383487438734, help="Integer seed")
args = parser.parse_args()
#Set seed and generate keyword
seed = args.seed
#Construct Matrix
f = open(args.inputFile,'r')
message = f.read()
Matrix = rv.Vigenere(seed)
Matrix.setMessage(message)
if(args.mode == 'encrypt'):
Matrix.encrypt()
else:
Matrix.decrypt()
o = open(args.outputFile,'w')
o.write(str(Matrix.ciphertext))
print("Seed used:",Matrix.seed)
print("Key Generated:",Matrix.keyWord)
print("Original Message:",Matrix.message)
print("Decoded Message:",Matrix.ciphertext)
if __name__ == '__main__':
main()
randomized_vigenere.py
(请务必将“<”、“=”和“>”添加到符号列表中。出于某种原因,它们不断从 post 中删除。)
import random
class Vigenere(object):
#Initialize Vigenere object.
#Sets the random seed based on integer passed to the object
#Establishes all valid symbols
#Generates empty matrix which will contain values for encryption/decryption
#Generates a keyword based on the integer passed to the object
def __init__(self, seed):
random.seed(seed)
self.seed = seed
self.symbols= """ !"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""
self.Table = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.keyWord = ""
self.message = ""
self.ciphertext = ""
self.keywordFromSeed(seed)
#Sets the plaintext that will be encrypted/decrypted
def setMessage(self,message):
self.message = message
#Generate psuedorandom keyword from seed
def keywordFromSeed(self,seed):
Letters = []
while seed > 0:
Letters.insert(0,chr((seed % 100) % 26 + 65))
seed = seed // 100
self.keyWord = "".join(Letters)
self.buildVigenere()
#Contructs a 95 x 95 matrix filled randomly with no repeats within same line
def buildVigenere(self):
random.seed(self.seed)
temp = list(self.symbols)
random.shuffle(temp)
temp = ''.join(temp)
for sym in temp:
random.seed(self.seed)
myList = []
for i in range(len(temp)):
r = random.randrange(len(temp))
if r not in myList:
myList.append(r)
else:
while(r in myList):
r = random.randrange(len(temp))
myList.append(r)
while(self.Table[i][r] != 0):
r = (r + 1) % len(temp)
self.Table[i][r] = sym
#Encryption function that iterates through both the message and the keyword
#and grabs values from Table based on the ordinal value of the current
#character being pointed to be the iterator
def encrypt(self):
for i in range(len(self.message)):
mi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.eRetrieve(ki,mi)
def eRetrieve(self,ki,mi):
row = ord(self.message[mi]) - 32
col = ord(self.keyWord[ki]) - 32
return self.Table[row][col]
#Decryption function that iterates through both the message and the keyword
#and grabs values from Table based on the ordinal value of the current
#keyWord character being pointed to be the iterator, then traversing the
#row that corresponds to that value. While traversing that row, once there
#is a match of the message value being searched for, take the iterator value
#and convert it to an ascii character. This is the decrypted character
def decrypt(self):
self.ciphertext = ""
for i in range(len(self.message)):
emi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.dRetrieve(ki,emi)
def dRetrieve(self,ki,emi):
n = len(self.symbols)
whichRow = ord(self.keyWord[ki]) - 32
for i in range(n):
if self.Table[i][whichRow] == self.message[emi]:
decryptChar = chr(i + 32)
return(decryptChar)
感谢@Eric-Levieil 的帮助
开始前澄清一下:我知道有类似的主题,但没有任何内容真正提供任何直接帮助。另外:这是一个 class 项目;所以我不想找任何人为我编写项目代码。提示和建议是我正在寻找的。 (我会为了这种事去找我的教授,但他懒得查他的电子邮件。)
该程序旨在获取用户提供的种子,根据整数生成密钥,然后生成一个 95 x 95 矩阵,其中所有可打印的 ascii 字符都可用于 encryption/decryption 目的。 (键全是 alpha,并且大写)
关键:所有单元格都必须随机化。见下图: Randomized Vigenere Matrix
下面我会post我的代码(Python当然不是我的强项,尽管我一定会接受建设性的批评。):
import random
class Vigenere(object):
def __init__(self, seed):
random.seed(seed)
#string containing all valid characters
self.symbols= """!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abcdefghijklmnopqrstuvwxyz{|}~"""
self.eTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.dTable = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.keyWord = ""
self.message = ""
self.ciphertext = ""
self.keywordFromSeed(seed)
def setMessage(self,message):
self.message = message
#Generate psuedorandom keyword from seed
def keywordFromSeed(self,seed):
Letters = []
while seed > 0:
Letters.insert(0,chr((seed % 100) % 26 + 65))
seed = seed // 100
self.keyWord = "".join(Letters)
self.buildVigenere()
#Contructs a 95 x 95 matrix filled randomly
def buildVigenere(self):
n = len(self.symbols)
#Build the vigenere matrix
for i in range(n):
temp = self.symbols
for j in range(n):
r = random.randrange(len(temp))
self.eTable[i][j] = temp[r]
#This line below does not fill entire matrix. Why?
self.dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
def encrypt(self):
for i in range(len(self.message)):
mi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.eRetrieve(ki,mi)
def decrypt(self):
for i in range(len(self.message)):
emi = i
ki = i % len(self.keyWord)
char = self.dRetrieve(ki,emi)
self.ciphertext = self.ciphertext + char
print(self.ciphertext)
def eRetrieve(self,ki,mi):
row = ord(self.message[mi]) - 32
col = ord(self.keyWord[ki]) - 32
print(row, col)
return self.eTable[row][col]
def dRetrieve(self,ki,emi):
n = len(self.symbols)
whichRow = ord(self.keyWord[ki]) - 32
whichCol = ord(self.message[emi]) - 32
return(self.dTable[whichRow][whichCol])
为了以防万一,这是我的 main.py:
import argparse
import randomized_vigenere as rv
def main():
#Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", dest="mode", default = "encrypt", help="Encrypt or Decrypt")
parser.add_argument("-i", "--inputfile", dest="inputFile", default = "inputFile.txt", help="Input Name")
parser.add_argument("-o", "--outputfile", dest="outputFile", default = "outputFile.txt", help="Output Name")
parser.add_argument("-s", "--seed", dest="seed", default =7487383487438734, help="Integer seed")
args = parser.parse_args()
#Set seed and generate keyword
seed = args.seed
#Construct Matrix
f = open(args.inputFile,'r')
message = f.read()
Matrix = rv.Vigenere(seed)
Matrix.setMessage(message)
if(args.mode == 'encrypt'):
Matrix.encrypt()
Matrix.setMessage(Matrix.ciphertext)
Matrix.decrypt()
else:
Matrix.decrypt()
o = open(args.outputFile,'w')
o.write(str(Matrix.ciphertext))
if __name__ == '__main__':
main()
我一直在使用默认种子:7487383487438734
我的明文:ABCdefXYZ
我要回答这个问题:
#This line below does not fill entire matrix. Why?
我认为这是你当前的问题。如果我没记错的话,这应该是你问题的第一行,而不是函数中的简单注释:
def buildVigenere(self):
n = len(self.symbols)
#Build the vigenere matrix
for i in range(n):
temp = self.symbols
for j in range(n):
r = random.randrange(len(temp))
self.eTable[i][j] = temp[r]
#This line below does not fill entire matrix. Why?
self.dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
我做的第一件事是构建一个独立的小示例,如下所示:
import random
def buildVigenere():
symbols= """!"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] ^_`abcdefghijklmnopqrstuvwxyz{|}~"""
n = len(symbols)
eTable = [[0 for i in range(len(symbols))] for i in range(len(symbols))]
dTable = [[0 for i in range(len(symbols))] for i in range(len(symbols))]
#Build the vigenere matrix
for i in range(n):
temp = symbols
for j in range(n):
r = random.randrange(len(temp))
eTable[i][j] = temp[r]
print (r, len(temp), j, len(symbols), temp[r])
#This line below does not fill entire matrix. Why?
print (ord(temp[r])-32)
dTable[j][(ord(temp[r])-32)] = chr(i+32)
temp = temp.replace(temp[r],'')
print dTable
buildVigenere()
如果你想在这里找到答案,你真的应该学会这样做,更普遍的是成为一名成功的程序员。找到问题所在,并能在简单的案例中重现,往往是关键。
这里我得到一个错误:
Exception "unhandled IndexError"
list assignment index out of range
我添加了一些打印语句(见上文),我发现错误来自 symbols
字符串中缺少 < > =
。
你为什么不使用 chr
来构建你的字符串 symbols
?
对于 buildVigenere
,您可以使用
random.shuffle(x)
我能够让它工作。我将 post 我的实现如下:
main.py
import argparse
import randomized_vigenere as rv
def main():
#Parse parameters
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mode", dest="mode", default = "encrypt", help="Encrypt or Decrypt")
parser.add_argument("-i", "--inputfile", dest="inputFile", default = "inputFile.txt", help="Input Name")
parser.add_argument("-o", "--outputfile", dest="outputFile", default = "outputFile.txt", help="Output Name")
parser.add_argument("-s", "--seed", dest="seed", default =7487383487438734, help="Integer seed")
args = parser.parse_args()
#Set seed and generate keyword
seed = args.seed
#Construct Matrix
f = open(args.inputFile,'r')
message = f.read()
Matrix = rv.Vigenere(seed)
Matrix.setMessage(message)
if(args.mode == 'encrypt'):
Matrix.encrypt()
else:
Matrix.decrypt()
o = open(args.outputFile,'w')
o.write(str(Matrix.ciphertext))
print("Seed used:",Matrix.seed)
print("Key Generated:",Matrix.keyWord)
print("Original Message:",Matrix.message)
print("Decoded Message:",Matrix.ciphertext)
if __name__ == '__main__':
main()
randomized_vigenere.py
(请务必将“<”、“=”和“>”添加到符号列表中。出于某种原因,它们不断从 post 中删除。)
import random
class Vigenere(object):
#Initialize Vigenere object.
#Sets the random seed based on integer passed to the object
#Establishes all valid symbols
#Generates empty matrix which will contain values for encryption/decryption
#Generates a keyword based on the integer passed to the object
def __init__(self, seed):
random.seed(seed)
self.seed = seed
self.symbols= """ !"#$%&'()*+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""
self.Table = [[0 for i in range(len(self.symbols))] for i in range(len(self.symbols))]
self.keyWord = ""
self.message = ""
self.ciphertext = ""
self.keywordFromSeed(seed)
#Sets the plaintext that will be encrypted/decrypted
def setMessage(self,message):
self.message = message
#Generate psuedorandom keyword from seed
def keywordFromSeed(self,seed):
Letters = []
while seed > 0:
Letters.insert(0,chr((seed % 100) % 26 + 65))
seed = seed // 100
self.keyWord = "".join(Letters)
self.buildVigenere()
#Contructs a 95 x 95 matrix filled randomly with no repeats within same line
def buildVigenere(self):
random.seed(self.seed)
temp = list(self.symbols)
random.shuffle(temp)
temp = ''.join(temp)
for sym in temp:
random.seed(self.seed)
myList = []
for i in range(len(temp)):
r = random.randrange(len(temp))
if r not in myList:
myList.append(r)
else:
while(r in myList):
r = random.randrange(len(temp))
myList.append(r)
while(self.Table[i][r] != 0):
r = (r + 1) % len(temp)
self.Table[i][r] = sym
#Encryption function that iterates through both the message and the keyword
#and grabs values from Table based on the ordinal value of the current
#character being pointed to be the iterator
def encrypt(self):
for i in range(len(self.message)):
mi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.eRetrieve(ki,mi)
def eRetrieve(self,ki,mi):
row = ord(self.message[mi]) - 32
col = ord(self.keyWord[ki]) - 32
return self.Table[row][col]
#Decryption function that iterates through both the message and the keyword
#and grabs values from Table based on the ordinal value of the current
#keyWord character being pointed to be the iterator, then traversing the
#row that corresponds to that value. While traversing that row, once there
#is a match of the message value being searched for, take the iterator value
#and convert it to an ascii character. This is the decrypted character
def decrypt(self):
self.ciphertext = ""
for i in range(len(self.message)):
emi = i
ki = i % len(self.keyWord)
self.ciphertext = self.ciphertext + self.dRetrieve(ki,emi)
def dRetrieve(self,ki,emi):
n = len(self.symbols)
whichRow = ord(self.keyWord[ki]) - 32
for i in range(n):
if self.Table[i][whichRow] == self.message[emi]:
decryptChar = chr(i + 32)
return(decryptChar)
感谢@Eric-Levieil 的帮助