核心是绕过固定位宽整型,用低位在前的vector逐位模拟竖式乘法;加密场景必须严格保精度,禁用近似,即时进位确保中间值不溢出,输出前剔除前导零并逆序。

直接用大数循环相乘算法解决 Long 溢出问题,核心不是“优化 Long”,而是彻底绕过固定位宽整型——改用可动态扩展的高精度结构逐位模拟乘法过程。加密场景对精度零容忍,不能取近似、不能丢位、不能依赖浮点或对数,必须保证每一位数字严格正确。
选对底层表示:倒序数组比字符串更可控
加密变量常以十六进制或十进制字符串输入(如 RSA 模幂中的大素数),但运算时别直接操作 string。应转为 低位在前的整型 vector(例如 "1234" → [4,3,2,1])。原因有三:
- 避免 string 拼接带来的频繁内存分配和拷贝,循环相乘中每轮都要累加中间结果,string 性能差且易引入空字符或编码错误;
- 数组索引直接对应数位权值(下标 i 对应 10ⁱ),错位相加(如 a[i] × b[j] → res[i+j])逻辑清晰,不易越界;
- 进位处理可就地完成:每次乘加后立刻做
res[k] %= 10和res[k+1] += res[k] / 10,不积压中间值,防止 int 短期内溢出(9×9 + 当前累加 ≤ 81 + 几十,仍在 int 安全范围内)。
循环相乘要分清两类场景:单个小因子 vs. 全高精度
加密计算中常见两种模式,实现方式不同:
- 大数 × 小整数(如密钥扩展中的常数倍):用单层循环即可。例如阶乘、SM2 中的标量乘法预计算。每位乘上该整数,再统一进位。代码简洁、无嵌套、O(n) 时间;
-
大数 × 大数(如 RSA 密钥生成中的 p×q):必须双层循环模拟竖式,i 遍历被乘数位,j 遍历乘数位,结果累加到 res[i+j]。注意 res 长度至少设为
a.size() + b.size(),否则res[i+j+1]可能越界;
进位策略决定稳定性和边界安全
不要等全部乘完再统一进位——中间值可能远超 int 上限(尤其当用 short 存数组时,9×9=81 已接近上限,再加累加极易溢出)。推荐「即时进位」:
- 每执行一次
res[i+j] += a[i] * b[j],立刻做:res[i+j+1] += res[i+j] / 10;res[i+j] %= 10; - 这样每个 res[k] 始终保持 0–9,后续操作不会因中间值过大而崩;
- 若想省空间,可用
unsigned short存单数字,但所有乘法运算前必须先转int,避免short × short自动提升失败或截断。
输出与校验不能省:去前导零 + 逆序打印 + 十六进制兼容
加密变量常需 hex 输出(如 DER 编码),所以最后一步不是简单倒序打印十进制:
- 先剔除高位连续零:
while (res.size() > 1 && res.back() == 0) res.pop_back(); - 再从
res.rbegin()到res.rend()输出,得到正常高位在前的字符串; - 若需 hex,把每 4 位十进制转成 1 位十六进制太慢,建议在输入阶段就支持 hex 字符串解析(如 "FF0A" → [10,0,15,15]),内部仍按十进制数组运算,输出时再整体转 hex——更稳,也方便与 OpenSSL 等库对接。











