如何修复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,正常输入不会有这个问题。如果确实报错,你可以试试这两个方案:
- 若后续还有
nextLine()操作,在读取p和q后加sc.nextLine();清空缓冲区的换行符; - 换用
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
相关产品推荐
相关产品推荐

