[英]Vigenere encryption using key as plaintext
我正在尝试编写一个 Vigenere 解密的变体,其中我的加密密钥是明文。 为此,我们假设我们知道密钥的第一个字母,假设它是 a0,那么代码必须使用 a0 来解密密钥a1的下一个字母,要解密a2 ,它必须使用a1 ,依此类推...使用密钥an-1解密字母 an。
我目前有以下代码使用通常的 Vigenere 方法进行加密和解密。 我想利用这段代码来执行我在开头提到的变体。
from random import sample
from itertools import product as col
def generator(key,char,length):
char_len = key.count(char)
key_piece = key[:length - char_len:]
list_keys = [key_piece+"".join(i) for i in list(col([chr(i) for i in range(65, 65+26)], repeat=char_len))]
return list_keys
`def vigenere(x,key):
lst_final = []
code = list(x)
j = 0
for i,char in enumerate(code):
if char.isalpha():
code[i] = key[(i+j)%len(key)]
if cifrar:
lst_final.append((ord(x[i]) + ord(code[i]) - 65 * 2) % 26)
else:
lst_final.append((ord(x[i]) - ord(code[i])) % 26)
else:
lst_final.append(ord(char))
j -=1
for i,char in enumerate(code):
if char.isalpha():
lst_final[i] = chr(lst_final[i] + 65)
else:
lst_final[i] = chr(lst_final[i])
return ''.join(lst_final)
print("Bienvenido al cifrado Vigenere")
if input('Cifrar o Descifrar : ').lower() == 'cifrar':
x = input('Ingrese el texto : ').upper()
key = input('Ingrese la clave : ').upper()
cifrar = True
print(vigenere(x,key))
else:
x = input('text : ').upper()
cifrar = False
if input('Tiene la clave? (y/n) : ') == "y":
key = input('Ingrese la clave : ').upper()
print(vigenere(x,key))
请注意,该程序以西班牙语运行。 我必须说我是一名数学家,我作为一名程序员的技能还有很多不足之处(我什至努力编写上面的代码),因此我感到有些失落,我希望有人能帮助我我一个提示或类似的东西。
编辑:根据评论我搜索了有关高压灭菌器密码的信息。 现在我有新的疑问,我想我的问题应该更具体一些,我会通过一个例子来做
这是一个虚构的例子。 假设我们有加密文本JLPWZ,我们知道密钥的第一个字母是Q。所以我搜索,使用Vigenere方法(Vigenere表)Q和J解密字母H,现在使用H和L解密E,然后E和P解密L,用L和W得到L,然后用L和Z得到O; 为了最终得到明文HELLO
解释
我对这个问题的理解是,给定纯文本(PT)的第一个字符被用作维吉尼亚密钥来加密该字符以给出第一个密文(CT)字符。 第一个 PT 字符然后再次用作加密第二个字符的密钥。 对于每个后续字符,前一个PT 字符用作加密密钥。
因此,要执行加密步骤的 function 必须首先使用第一个 PT 字符作为密钥两次,然后再为每个后续加密密钥推进一个字符。
这是使用此方法的简单javascript加密例程的工作片段。
加密 function (javascript):
PT = "KEEPTHISMESSAGEPRIVATE"; key = PT.charAt(0); console.log(encryptVigenere(PT,key)); function encryptVigenere(PT,key,alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ") { let CT = ""; for (let i=0; i<PT.length; i++) { CT += alphabet.charAt((alphabet.indexOf(key)+alphabet.indexOf(PT.charAt(i)))%26); key = PT.charAt(i); } // next PT char; return CT; } // end function encryptVigenere;
for-next
循环包括一个单行算法,如果字母位置被认为是字母表的相关部分之间的距离,则可以通过检查维吉尼亚白板的交点来理解和推导该算法。 参见例如: https://www.britannica.com/topic/Vigenere-cipher 。
除以 26 %26
的余数用于确保字符 position 始终在字母表的范围内(其“距离”/长度为 26 个字符)。 对于循环的每次迭代,密钥也会提前一个字符(最后,允许第一次迭代使用与第二次相同的密钥)。
解密function(javascript):
解密过程要求解密第一个 CT 字符所需的字符与接收方交换,并且它必须是已知 PT 的第一个字符。
const CT = "UOITIAPAEQWKSGKTGZDVTX"; let key = "K"; console.log(decryptVigenere(CT,key)); function decryptVigenere(CT,key,alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ") { let PT = ""; for (let i=0; i<CT.length; i++) { key = alphabet.charAt((alphabet.indexOf(CT.charAt(i))-alphabet.indexOf(key) +26)%26); PT += key; } // next CT char; return PT; } // end function decryptVigenere;
同样,该算法可以通过检查 Vigenere 表上字母之间的距离来解释。 因为解密需要减去字母距离,所以在最终余数除以 26 之前加 26 进行调整,以确保字符始终在字母表的长度 (26) 内。
重要的部分是每次循环都会将密钥重置为当前解密的明文结果。
在这两个函数中,都可以发送修改后的字母表作为默认 AZ 的替代。
将原理应用到 python
假设 python 有识别已知位置字符的字符串方法,并且可以找到已知字符的 position,这里使用的算法应该可以直接转移到 python。过程的每个部分都是一个与 position 和/或距离相关的数字其他职位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.