【问题标题】:Polyalphabetic cipher in python, decode method doesn't workpython中的多字母密码,解码方法不起作用
【发布时间】:2022-01-16 08:59:51
【问题描述】:

我正在尝试在 Python 中实现一些基本密码。我坚持的是多字母密码。我在这里看到其他帖子使用相同的术语来表示似乎是不同的密码,所以我将指定我正在尝试实现 this textbook 在第 7 章第 1 节中所说的多字母密码。这涉及将消息数字化,将其分解为等长的向量,将每个向量乘以一个集合矩阵(即可逆,模 26),添加一个移位向量,然后反转数字化以得到编码的消息。

使用教科书中的示例,我正在尝试使用矩阵 [[3, 5], [1, 2]] 和移位向量 [2, 2] 对“HELP”进行编码,并且它正在编码为“RRGR “正如书中所说的那样。但是,当我将解码方法应用于“RRGR”到“HELO”时。如果更多数据有帮助,我会补充一点,当我使用相同的矩阵和移位向量对整个字母进行编码然后解码时,我会得到“ABCDEFGGHJKLMNOPQRSTUVWWYZ”。

我的代码如下(抱歉缺少cmets,这段代码不重要,所以我没有打扰):

import numpy as np

class Polyalphabetic:
    def __init__(self, alphabet, vec_len, shift, mult):
        self.alphabet = alphabet
        self.vec_len = vec_len
        self.mod = len(alphabet)
        self.shift = np.array(shift)
        self.mult = np.array(mult)
        self.inv = np.linalg.inv(mult) % self.mod

    def digitize(self, string):
        return [alphabet.index(letter) for letter in string]

    def undigitize(self, int_list):
        return ''.join([alphabet[i] for i in int_list])

    def encode(self, message):
        digits = self.digitize(message)

        output_vectors = []
        for i in range(len(digits) // self.vec_len):
            in_vec = digits[self.vec_len * i : self.vec_len * (i + 1)]
            multed_vec = np.matmul(self.mult, in_vec)
            shifted_vec = (multed_vec + self.shift)
        
            out_vec = shifted_vec.astype(int) % self.mod
            output_vectors.append(out_vec)
    
        encoded = np.concatenate(output_vectors)
        return self.undigitize(encoded)

    def decode(self, encoded_message):
        digits = self.digitize(encoded_message)
    
        output_vectors = []
        for i in range(len(digits) // self.vec_len):
            in_vec = digits[self.vec_len * i : self.vec_len * (i + 1)]
            shifted_vec = (in_vec - self.shift)
            multed_vec = np.matmul(self.inv, shifted_vec)
        
            out_vec = multed_vec.astype(int) % self.mod
            output_vectors.append(out_vec)
    
        decoded = np.concatenate(output_vectors)
        return self.undigitize(decoded)


alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

b = [2, 2]
A = [
    [3, 5],
    [1, 2]
]

Poly = Polyalphabetic(alphabet, 2, b, A)
print(Poly.encode(alphabet))
# Output is "HEXKNQDWTCJIZOPUFAVGLMBSRY"
print(Poly.decode(Poly.encode(alphabet)))
# Output is "ABCDEFGGHJKLMNOPQRSTUVWWYZ"

【问题讨论】:

    标签: python encryption cryptography


    【解决方案1】:

    我已经找到了一个解决方案,但我仍然不太确定为什么它首先会被破坏。我用out_vec = np.rint(multed_vec).astype(int) % self.mod 替换了out_vec = multed_vec.astype(int) % self.mod 行,因为出于某种原因,numpy 的array.astype(int) 有时会舍入应该是整数的值。我的猜测是这是一个浮点错误,numpy 显示的值略低于 15(HELP 中的 P)为15.,但是当它被转换为整数时,它丢弃了小数位并得到 14(HELO 中的 O) .

    跟进我遇到的另一个问题的解决方案。我的代码要求乘数矩阵具有行列式 1 或 -1 以便与所有整数条目进行逆运算,因为获得逆运算涉及除以行列式。为了解决这个问题,我的第一种方法是将倒数乘以乘数的行列式,但它根本不是乘数的倒数,因为条目太大了。为了解决这个问题,我必须将它乘以行列式的模乘逆(数字 i 使得 det(A) * i = 1 (mod 26))。这使倒数恢复为实际上是乘数的倒数,但没有重新引入逆的初始计算中涉及的分数。

    【讨论】:

      猜你喜欢
      • 2015-12-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      相关资源
      最近更新 更多