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

Java仿射移位密码解密代码问题:明文正确但b值错误

仿射密码解密中密钥b值错误的问题排查

问题概述

编写Java代码解密仿射移位密码时,输出的明文正确,但密钥的b值与预期不符。以下是问题代码:

public void solve() {
    double bestSpell = Double.NEGATIVE_INFINITY;  // Start with the worst possible spelling score
    String bestDecode = "";

    // Loop over all possible values of 'a'
    for (int a = 1; a < 26; a++) {
        int a_inv = 0;

        // Find a^-1 (the modular multiplicative inverse of a)
        for (int i = 1; i < 26; i++) {
            if ((a * i) % 26 == 1) {
                a_inv = i;
                break;
            }
        }

        // If no valid modular inverse, skip this 'a'
        if (a_inv == 0) continue;

        // Loop over all possible values of 'b'
        for (int b = 0; b < 26; b++) {
            StringBuilder output = new StringBuilder();

            // Apply decryption formula for each character in the ciphertext
            for (int i = 0; i < strippedCT.length(); i++) {
                if (strippedCT.charAt(i) != ' ') {
                    int x = strippedCT.charAt(i) - 'A';  // Convert character to 0-25 range
                    int decodedValue = (a_inv * (x - b + 26)) % 26;  // Ensure non-negative result
                    output.append((char) (decodedValue + 'A'));  // Convert back to character
                } else {
                    output.append(' ');
                }
            }

            // Check the spelling score
            double currentSpell = sc.spellCheck(output.toString());

            // Update best found key if this one is better
            if (currentSpell > bestSpell) {
                bestA = a;
                bestB = b;
                bestDecode = output.toString();
                bestSpell = currentSpell;
            }
        }
    }

    // Output the best results
    System.out.println("Solved as mono");
    System.out.println("A: " + bestA + " B: " + bestB);
    System.out.println(bestDecode);
    this.plaintext = bestDecode;
}

核心原因分析

1. 短密文导致多密钥命中相同有效明文

如果测试用的密文长度过短,可能存在多组不同的(a,b)密钥对,解密后得到的短文本恰好是有意义的明文(或拼写得分相同)。此时代码会保留最后一个遍历到的高得分密钥对,而非实际加密时使用的密钥。

2. 拼写检查函数的得分歧义

若拼写检查函数对多个不同明文返回相同的最高得分,代码会选择最后一个遍历到的密钥对。比如短文本中,不同的解密结果可能都是合法单词,得分相同。

3. 密钥概念混淆

仿射密码存在两种密钥表述方式:

  • 加密密钥:(a, b),对应加密公式 E(x) = (a*x + b) mod 26
  • 解密密钥:(a⁻¹, c),其中 c = (-a⁻¹*b) mod 26,对应解密公式 D(y) = (a⁻¹*y + c) mod 26

若你误将解密密钥中的c当作预期的b值,会误以为代码输出的b错误,但实际上代码输出的是正确的加密密钥b。

解决方案

1. 使用更长的测试密文

确保密文长度足够(至少10个字符以上),这样不同密钥对解密出的明文差异会被放大,拼写检查得分会出现明显区分,只有正确的密钥对会得到最高得分。

2. 优化拼写检查逻辑

改进拼写检查函数,让正确明文的得分显著高于其他候选结果。例如:

  • 增加完整单词匹配的权重
  • 结合英文字母频率统计(E、T等高频字母的出现占比)

3. 验证密钥正确性

找到密钥后,可通过加密反向验证:用得到的(bestA, bestB)加密解密出的明文,看是否与原密文完全一致。若一致,说明密钥正确,只是你的预期存在偏差。

4. 锁定首个最高得分密钥

若需优先保留第一个找到的正确密钥,可保持原代码的更新逻辑(仅当得分更高时替换),这样首个达到最高得分的密钥会被保留,不会被后续得分相同的密钥覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:02:05