base62 编码与 bigint 协同解决超大整数 url 短链问题:base62 提供无特殊字符的紧凑编码,bigint 保障超 9e15 id 的无损运算与进制转换,二者结合实现安全、双向一致的短码生成与解析。

理解 Base62 编码与 BigInt 的协同价值
Base62(由 0–9、a–z、A–Z 共 62 个字符组成)是 URL 友好的短编码方案,比 Base64 少了 +、/ 和 = 等需转义字符。而原始 URL ID(如数据库自增主键)可能极大——超过 Number.MAX_SAFE_INTEGER(≈9e15),此时 Number 类型会丢失精度。BigInt 正好填补这一空白:它能无损表示任意长度整数,且支持除法、取余等基本运算,天然适配进制转换逻辑。
定义 Base62 字符集并实现编码(ID → 短码)
编码本质是将一个非负 BigInt 转为 Base62 进制字符串。关键点在于:BigInt 不支持 % 对字符串取模,但支持 % 对 BigInt 取模;除法需用 BigInt(quotient) 截断而非 Math.floor(后者不支持 BigInt)。
- 定义字符映射:
const BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - 编码函数接收
id: bigint,循环执行:id % 62n得当前位索引,查表取字符;再令id = id / 62n(自动向下取整) - 结果字符需逆序拼接(因低位先算出)
- 特别处理
0n:直接返回"0",否则循环不进
实现解码(短码 → ID)并确保双向无损
解码是编码的逆过程:从左到右遍历短码每个字符,在 BASE62 中查其索引值,累加 acc = acc * 62n + index。注意所有中间量必须为 BigInt,包括初始值 0n 和乘数 62n。
- 逐字符校验:若某字符不在 BASE62 中,立即抛错或返回
null,避免静默错误 - 空字符串、全零串(如
"00")应视为非法,因编码器不会生成前导零——这是 Base-N 编码的自然规范 - 验证闭环:对任意合法
id,执行encode(id)再decode(encode(id))必须严格等于原id
在 URL 短链服务中安全集成 BigInt Base62
实际部署时需注意运行时兼容性与数据流一致性:
- Node.js ≥ 10.4 或现代浏览器(Chrome 67+)原生支持 BigInt;旧环境需 Babel 插件或放弃 BigInt 改用
jsbi库模拟 - 数据库存储 ID 时,若用 PostgreSQL,可存为
BIGINT(最大 2⁶³−1);更大值建议存为文本或使用NUMERIC类型 - HTTP 接口传参时,URL 中的短码是字符串,后端收到后直接解码;但若 API 同时暴露原始 ID(如
/api/links/12345),该数字必须以字符串形式传递,再转为BigInt,不可用parseInt或一元加号(+),否则溢出











