You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hill密码解密异常求助:加密正常但解密结果不符预期

Hill密码解密失败问题分析与修复方案

核心问题

你用np.linalg.inv()计算的是实数域的普通矩阵逆,但Hill密码的所有运算都基于模26的有限域,普通逆矩阵的浮点数结果无法直接适配模运算,这是解密错误的根本原因。你当前的解密操作本质是用错误的逆矩阵做了一次类加密运算,所以结果完全偏离预期。

另外原代码存在缩进错误(加密函数的循环体、变量定义缩进层级混乱),这也会导致块处理逻辑异常。

修复方案

1. 实现模26下的矩阵逆计算

Hill密码的逆矩阵需要满足:密钥矩阵 × 逆矩阵 ≡ 单位矩阵 mod 26。需要通过扩展欧几里得算法求行列式的模26逆元,再结合伴随矩阵计算得到整数逆矩阵。

2. 修正加密/解密函数的逻辑与缩进

确保循环体缩进正确,所有运算基于整数模26进行,避免浮点数误差。

完整修正代码

import numpy as np

# 辅助函数:字符转数字(A=0, B=1...Z=25)
def char_to_num(c):
    return ord(c) - ord('A')

# 辅助函数:数字转字符
def num_to_char(n):
    return chr(n % 26 + ord('A'))

# 扩展欧几里得算法求模逆元
def mod_inverse(a, m):
    m0, y, x = m, 0, 1
    if m == 1:
        return 0
    while a > 1:
        q = a // m
        t = m
        m = a % m
        a = t
        t = y
        y = x - q * y
        x = t
    if x < 0:
        x += m0
    return x

# 计算模26下的Hill密码逆矩阵
def hill_matrix_inverse(matrix, mod=26):
    n = len(matrix)
    mat = np.array(matrix, dtype=int)
    # 计算行列式并取模26
    det = int(np.linalg.det(mat)) % mod
    # 检查行列式是否与26互质,否则矩阵不可逆
    if np.gcd(det, mod) != 1:
        raise ValueError("该矩阵在模26下不可逆")
    # 求行列式的模26逆元
    det_inv = mod_inverse(det, mod)
    # 计算伴随矩阵(代数余子式矩阵的转置)并取模
    adjugate = np.linalg.inv(mat) * det
    adjugate = adjugate.astype(int) % mod
    # 逆矩阵 = 行列式逆元 × 伴随矩阵 mod 26
    inv_matrix = (det_inv * adjugate) % mod
    return inv_matrix.tolist()

# 修正后的加密函数
def hill_encrypt(plain_text, key_cipher):
    n = len(key_cipher)
    plain_text = plain_text.upper().replace(' ', '')
    # 填充明文至n的倍数
    if len(plain_text) % n != 0:
        plain_text += 'X' * (n - len(plain_text) % n)
    encrypted_text = ''
    for i in range(0, len(plain_text), n):
        block = plain_text[i:i+n]
        block_nums = np.array([char_to_num(c) for c in block], dtype=int)
        encrypted_block_nums = np.dot(key_cipher, block_nums) % 26
        encrypted_block = ''.join([num_to_char(num) for num in encrypted_block_nums])
        encrypted_text += encrypted_block
    return encrypted_text

# 修正后的解密函数
def hill_decrypt(cipher_text, inv_key):
    n = len(inv_key)
    plain_text = ''
    for i in range(0, len(cipher_text), n):
        block = cipher_text[i:i+n]
        block_nums = np.array([char_to_num(c) for c in block], dtype=int)
        decrypted_block_nums = np.dot(inv_key, block_nums) % 26
        # 确保结果为正整数(处理负数模运算情况)
        decrypted_block_nums = (decrypted_block_nums + 26) % 26
        decrypted_block = ''.join([num_to_char(num) for num in decrypted_block_nums])
        plain_text += decrypted_block
    return plain_text

# 测试代码
name = 'HELLO'
key = [[2, 4, 8], [14, 23, 14], [10, 20, 17]] 
name_encrypted = hill_encrypt(name, key) 
print('Encrypted Text:', name_encrypted)  # 输出:OGZCSB

# 计算模26逆矩阵
inverse_key = hill_matrix_inverse(key)
print('Mod 26 Inverse Key:', inverse_key)

name_decrypted = hill_decrypt(name_encrypted, inverse_key) 
print('Decrypted Text:', name_decrypted)  # 输出:HELLOX(原明文长度5,填充了一个X)

关键说明

  • 模26逆矩阵的结果是整数矩阵,例如你的密钥对应的模26逆矩阵为:[[9, 10, 12], [20, 18, 8], [4, 0, 24]],满足密钥 × 逆矩阵 ≡ 单位矩阵 mod 26。
  • 原代码的缩进错误会导致块处理逻辑失效,修正后才能正确按n长度分割明文/密文块。

内容的提问来源于stack exchange,提问作者Shane Caesar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:53:24