Java中实现char数组与long互转(非Long.parseLong等方法)适配RSA加密
解决RSA明文与long的互转问题
先修正你的正向转换代码
你提供的charArrayToLong存在两处关键问题:
return sum写在for循环内部,会导致第一次循环就直接返回,逻辑完全错误;bi[i] - '0'是将字符转为对应数字(比如'9'转成9),而非你需要的字符本身的ASCII/Unicode数值。
以下是修正后的正向转换方法,实现将String按每个字符的数值,通过幂次累加转为long:
public static long stringToLong(String input) { char[] chars = input.toCharArray(); long sum = 0; int len = chars.length; // 每个char是16位,用2^16作为进制基数;若仅需ASCII(8位),可改为BASE=256 final long BASE = 65536; for (int i = 0; i < len; i++) { // 计算当前字符的权重:BASE^(len-1 - i) long weight = 1; for (int j = 0; j < len - 1 - i; j++) { weight *= BASE; // 提前检测long溢出,避免无效转换 if (weight < 0) { throw new IllegalArgumentException("输入字符串过长,超出long存储范围"); } } sum += (long) chars[i] * weight; if (sum < 0) { // 溢出二次校验 throw new IllegalArgumentException("输入字符串过长,超出long存储范围"); } } return sum; }
注意:long是64位有符号整数,最多能存储3个16位char(65536^2 * 65535 = 281474976710655 < long最大值9223372036854775807);若使用ASCII(8位,BASE=256),最多可存储7个ASCII字符,超出长度会抛出异常。
反向转换:long转回String
对应正向逻辑,反向转换需要将long按BASE拆分出每个字符的数值,再转回char:
public static String longToString(long value, int charCount) { // 必须传入字符数量,否则无法确定拆分位数 final long BASE = 65536; // 和正向转换的BASE保持一致 char[] chars = new char[charCount]; long remaining = value; for (int i = charCount - 1; i >= 0; i--) { // 提取当前位的字符数值 chars[i] = (char) (remaining % BASE); remaining = remaining / BASE; } // 校验剩余值,避免输入的long不符合转换规则 if (remaining != 0) { throw new IllegalArgumentException("输入的long值无法拆分为指定数量的字符"); } return new String(chars); }
使用示例
public static void main(String[] args) { String original = "abc"; // 3个字符,符合long存储范围 long converted = stringToLong(original); System.out.println("转换后的long值:" + converted); String restored = longToString(converted, original.length()); System.out.println("恢复后的字符串:" + restored); // 输出abc }
关于RSA的额外说明
实际RSA加密不会直接把整个明文转成一个long(long长度限制过大,仅能存储少量字符),通常的做法是:
- 将明文拆分为固定长度的块(每个块大小小于密钥模n的长度);
- 对每个块单独加密;
- 解密时将每个块解密后拼接。
如果你的密钥模n用long存储,密钥长度最多64位,安全性完全不足,建议使用Java的BigInteger处理大数运算,它无长度限制,更适配RSA实现。
内容的提问来源于stack exchange,提问作者The Dog on the Log
相关产品推荐
相关产品推荐

