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

Java实现Vigenere密码解密失败,请求排查代码问题

问题分析与修复代码

核心问题

你的解密逻辑完全没有执行字符转换操作——当mode为D时,代码仅修改了shift值,但没有对字符c进行解密计算,也没有更新keywordIndex。这就导致解密时字符根本没被处理,输出自然和输入一致,看起来像“再次加密”。

另外还有两个次要问题:

  • 加密时先计算再转大写,若输入是小写字母,c - 'A'会得到负数,导致计算结果错误
  • 解密时直接用26 - shift,但字符计算时未考虑模运算的负数情况

修复后的代码

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Do you want to encrypt or decrypt? (E/D): ");
        String mode = scanner.nextLine().toUpperCase();
        System.out.print("Input file name: ");
        String inputFileName = scanner.nextLine();
        System.out.print("Output file name: ");
        String outputFileName = scanner.nextLine();
        System.out.print("Keyword (all capitals): ");
        String keyword = scanner.nextLine().toUpperCase();
        scanner.close();
        
        try {
            BufferedReader reader = new BufferedReader(new FileReader(inputFileName));
            BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileName));
            
            int keywordIndex = 0;
            String line = reader.readLine();
            while (line != null) {
                for (int i = 0; i < line.length(); i++) {
                    char c = line.charAt(i);
                    if (Character.isLetter(c)) {
                        // 先统一转大写,避免小写字母计算错误
                        c = Character.toUpperCase(c);
                        int shift = keyword.charAt(keywordIndex) - 'A';
                        
                        if (mode.equals("D")) {
                            // 解密时用减法,加26再模26避免负数错误
                            c = (char) (((c - 'A' - shift) % 26 + 26) % 26 + 'A');
                        } else {
                            // 加密时的计算,模26确保在字母范围内
                            c = (char) (((c - 'A' + shift) % 26) + 'A');
                        }
                        // 无论加密解密,都要更新关键词索引
                        keywordIndex = (keywordIndex + 1) % keyword.length();
                    }
                    writer.write(c);
                }
                writer.newLine();
                line = reader.readLine();
            }
            reader.close();
            writer.close();
            
            System.out.println("Done.");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

修复说明

  1. 统一字符大小写:先把字母转成大写再计算,避免小写字母参与运算时出现负数偏移
  2. 解密逻辑补全:解密分支中添加了字符转换代码,并且无论加密还是解密,都会更新keywordIndex,确保关键词循环使用正确
  3. 处理模运算负数:解密时用((c - 'A' - shift) % 26 + 26) % 26,确保即使计算结果为负数,也能转换为0-25之间的正数,正确映射回字母

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:02:41