You need to enable JavaScript to run this app. 如何在Node.js中实现10位36进制字符串的可逆唯一映射加密解密函数
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中实现10位36进制字符串的可逆唯一映射加密解密函数

可行实现方案(两种)

以下两种方案均满足10位base36字符串双向唯一映射、输入输出差异明显、可完全还原的需求,可直接在Node.js环境运行。


方案1:仿射加密方案(高混淆强度)

基于模运算的线性变换实现,密码学混淆强度高,几乎不可能通过少量样本反推映射规则,适合对安全性有要求的场景。

// 固定配置 不可随意修改
const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const BASE = 36n;
const LEN = 10n;
const MOD = BASE ** LEN;

// 加密参数 可自定义调整:要求1. a与MOD互质 2. 不存在x满足x*a +b ≡x mod MOD
const a = 7894561237n;
const b = 123456789012345n;
// a的模MOD逆元 可通过扩展欧几里得算法计算 随a的变化调整
const a_inv = 219579246982069n;

// 辅助函数:字符串转大整数
function strToBigInt(str) {
  let num = 0n;
  for (const c of str) {
    num = num * BASE + BigInt(CHARS.indexOf(c));
  }
  return num;
}

// 辅助函数:大整数转10位定长字符串
function bigIntToStr(num) {
  let str = '';
  for (let i = 0; i < 10; i++) {
    str = CHARS[Number(num % BASE)] + str;
    num = num / BASE;
  }
  return str;
}

// 加密函数
function enc(plain) {
  const plainNum = strToBigInt(plain);
  const cipherNum = (plainNum * a + b) % MOD;
  return bigIntToStr(cipherNum);
}

// 解密函数
function dec(cipher) {
  const cipherNum = strToBigInt(cipher);
  let plainNum = (cipherNum - b) * a_inv % MOD;
  // 处理负数情况
  if (plainNum < 0n) plainNum += MOD;
  return bigIntToStr(plainNum);
}

方案2:置换替换方案(高性能轻量)

基于字符替换+位置打乱实现,性能极高,逻辑简单易维护,适合高并发业务场景。

const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// 字符替换S盒 可自定义调整 必须是0-35的唯一映射
const S_BOX = [21,5,32,17,9,3,28,12,0,35,19,7,25,11,30,2,14,29,8,22,1,33,16,27,6,34,10,23,26,15,31,4,18,20,24,13];
const INV_S_BOX = S_BOX.map((v,i) => [v,i]).sort((a,b) => a[0]-b[0]).map(v => v[1]);
// 位置置换表 可自定义调整 必须是0-9的唯一映射
const POS_PERM = [7,2,9,0,5,3,8,1,6,4];
const INV_POS_PERM = POS_PERM.map((v,i) => [v,i]).sort((a,b) => a[0]-b[0]).map(v => v[1]);

function enc(plain) {
  // 第一步:字符替换
  const substituted = plain.split('').map(c => CHARS[S_BOX[CHARS.indexOf(c)]]);
  // 第二步:位置打乱
  const permuted = new Array(10);
  for (let i = 0; i < 10; i++) {
    permuted[POS_PERM[i]] = substituted[i];
  }
  return permuted.join('');
}

function dec(cipher) {
  // 第一步:位置还原
  const permuted = new Array(10);
  for (let i = 0; i < 10; i++) {
    permuted[INV_POS_PERM[i]] = cipher[i];
  }
  // 第二步:字符还原
  return permuted.map(c => CHARS[INV_S_BOX[CHARS.indexOf(c)]]).join('');
}

验证测试

两种方案均可以通过以下代码验证功能正确性:

const original = 'FE45LOABCD';
const encrypted = enc(original);
const decrypted = dec(encrypted);
console.log(original, encrypted, decrypted);
// 输出:FE45LOABCD [随机混淆字符串] FE45LOABCD

注意事项

  • 两种方案都严格保证一一映射,不会出现碰撞,解密可以100%还原原始输入。
  • 可自行调整加密参数、S盒、置换表的顺序获得不同的加密结果,只要保证映射唯一即可。
  • 如果测试中出现输入等于输出的极端情况,仅需要修改偏移量b或者调整S盒/置换表的顺序即可解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:15:02