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

如何修复Java实现RSA算法中的Scanner资源泄漏问题

解决RSA实现中的Scanner关闭问题和第19行错误

我来帮你搞定这两个问题,顺便整理优化下你的代码:

一、Scanner关闭问题

你说调用sc.close()没效果,核心原因是关闭时机不对。Scanner必须在所有输入操作完成后再关闭,要是提前关了,后续代码再碰Scanner就会报错;如果把关闭语句放在类的末尾而非main方法里,那代码根本不会执行到它。

正确的做法是:等你读完message、p、q所有输入后,在main方法的末尾、return语句之前添加sc.close();。这样既能确保所有输入都读取完毕,又能正确释放Scanner的资源。

二、第19行的错误排查

假设你说的第19行是message = sc.nextLine();(不同IDE的行数统计可能略有差异),这行最常见的问题是输入缓冲区残留的换行符导致读取空字符串。不过看你的代码顺序是先读message再读p和q,正常输入不会有这个问题。如果确实报错,你可以试试这两个方案:

  1. 若后续还有nextLine()操作,在读取p和q后加sc.nextLine();清空缓冲区的换行符;
  2. 换用sc.nextLine()读取p和q,再手动转成整数,彻底避开缓冲区问题:
    System.out.println("Enter value of p and q (separated by space):");
    String pqInput = sc.nextLine();
    String[] pq = pqInput.split(" ");
    p = Integer.parseInt(pq[0]);
    q = Integer.parseInt(pq[1]);
    

另外也可能是IDE缓存的锅,试试重启IDE或者清理项目缓存。

修正后的完整代码

下面是整合了Scanner正确关闭、优化输入处理的完整代码:

import java.util.*;
public class RSA {
    static int gcd(int m, int n) {
        while (n != 0) {
            int r = m % n;
            m = n;
            n = r;
        }
        return m;
    }
    public static void main(String args[]) {
        int p = 0, q = 0, n = 0, e = 0, d = 0, phi = 0;
        int nummes[] = new int[100];
        int encrypted[] = new int[100];
        int decrypted[] = new int[100];
        int i = 0, j = 0, nofelem = 0;
        Scanner sc = new Scanner(System.in);
        String message;
        
        System.out.println("Enter the Message to be encrypted:");
        message = sc.nextLine();
        
        System.out.println("Enter value of p and q (separated by space):");
        // 用nextLine读取并拆分,避免缓冲区问题
        String[] pqInput = sc.nextLine().split(" ");
        p = Integer.parseInt(pqInput[0]);
        q = Integer.parseInt(pqInput[1]);
        
        // 关闭Scanner,所有输入操作已完成
        sc.close();
        
        n = p * q;
        phi = (p - 1) * (q - 1);
        
        // 寻找公钥e
        for (i = 2; i < phi; i++) {
            if (gcd(i, phi) == 1) {
                break;
            }
        }
        e = i;
        
        // 寻找私钥d
        for (i = 2; i < phi; i++) {
            if ((e * i - 1) % phi == 0) {
                break;
            }
        }
        d = i;
        
        // 将消息转为数字(仅支持小写字母)
        for (i = 0; i < message.length(); i++) {
            char c = message.charAt(i);
            nummes[i] = c - 96;
        }
        nofelem = message.length();
        
        // 加密
        for (i = 0; i < nofelem; i++) {
            encrypted[i] = 1;
            for (j = 0; j < e; j++) {
                encrypted[i] = (encrypted[i] * nummes[i]) % n;
            }
        }
        
        System.out.println("\nEncrypted message:");
        for (i = 0; i < nofelem; i++) {
            System.out.print(encrypted[i]);
            System.out.print((char) (encrypted[i] + 96));
        }
        
        // 解密
        for (i = 0; i < nofelem; i++) {
            decrypted[i] = 1;
            for (j = 0; j < d; j++) {
                decrypted[i] = (decrypted[i] * encrypted[i]) % n;
            }
        }
        
        System.out.println("\nDecrypted message:");
        for (i = 0; i < nofelem; i++) {
            System.out.print((char) (decrypted[i] + 96));
        }
        
        return;
    }
}

额外提示

  • 目前你的实现只支持小写字母,且输入的p、q必须是质数,使用时要注意;
  • 寻找私钥d的方式可以换成扩展欧几里得算法,效率会更高,适合处理大数值的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 21:22:43