如何改进代码生成高安全性、合规的StoreId与TransactionId编码Docket Number?
优化StoreId+TransactionId生成防破解Docket Number方案
需求与现有问题
基于最大3位的StoreId和最大5位的TransactionId生成编码后的Docket Number,要求:
- 编码唯一
- 长度≤9位
- 便于用户读取与复制
现有代码通过反转ID+加减密钥实现编码,但混淆逻辑过于简单,易被第三方破解,需优化提升安全性。
现有代码实现
let myTransKey = 19651; let myStoreKey = 186; function generateShortCode(storeId, transactionId) { //reverse the ids and then add the respective key var SID = storeId.toString().split("").reverse().join(""); SID = parseInt(SID) + myStoreKey; var TID = transactionId.toString().split("").reverse().join(""); TID = parseInt(TID) + myTransKey; var docketNum = `${SID}-${TID}`; return docketNum; } function decodeShortCode(shortCode) { shortCode = shortCode.split("-"); var storeID = shortCode[0]; var transactionID = shortCode[1]; //subtract the same key and then reverse the ids again storeID = parseInt(storeID.toString()) - myStoreKey; storeID = storeID.toString().split("").reverse().join(""); transactionID = parseInt(transactionID.toString()) - myTransKey; transactionID = transactionID.toString().split("").reverse().join(""); return { storeId: parseInt(storeID), shopDate: new Date(), transactionId: parseInt(transactionID) }; }
优化方案
核心优化思路
- 替换简单的反转+加减逻辑,改用自定义字符集进制转换+固定偏移混淆,既保证唯一性,又大幅提升破解门槛
- 严格控制编码长度,确保最终结果远低于9位限制
- 剔除易混淆字符,提升用户读取、复制的准确性
优化后代码实现
// 自定义字符集:排除0/O、1/I/l等易混淆字符,共32个字符(适配2^5进制,便于计算) const CHAR_SET = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'; const CHAR_SET_LEN = CHAR_SET.length; // 混淆偏移密钥(建议随机生成后固定,不要使用有规律的数值) const STORE_OFFSET = 127; const TRANS_OFFSET = 8193; /** * 生成防破解的Docket Number * @param {number} storeId 0-999的整数 * @param {number} transactionId 0-99999的整数 * @returns {string} 固定7位的编码 */ function generateDocketNumber(storeId, transactionId) { // 输入合法性校验 if (!Number.isInteger(storeId) || storeId < 0 || storeId > 999) { throw new Error('StoreId必须是0-999的整数'); } if (!Number.isInteger(transactionId) || transactionId < 0 || transactionId > 99999) { throw new Error('TransactionId必须是0-99999的整数'); } // 混淆StoreId并转3位32进制(32^3=32768 > 999+127=1126,足够容纳) let obfuscatedStore = storeId + STORE_OFFSET; let storeCode = ''; for (let i = 0; i < 3; i++) { storeCode = CHAR_SET[obfuscatedStore % CHAR_SET_LEN] + storeCode; obfuscatedStore = Math.floor(obfuscatedStore / CHAR_SET_LEN); } // 混淆TransactionId并转4位32进制(32^4=1048576 > 99999+8193=108192,足够容纳) let obfuscatedTrans = transactionId + TRANS_OFFSET; let transCode = ''; for (let i = 0; i < 4; i++) { transCode = CHAR_SET[obfuscatedTrans % CHAR_SET_LEN] + transCode; obfuscatedTrans = Math.floor(obfuscatedTrans / CHAR_SET_LEN); } // 拼接后得到固定7位的编码 return storeCode + transCode; } /** * 解码Docket Number * @param {string} docketNum 7位编码字符串 * @returns {object} 包含storeId、transactionId的对象 */ function decodeDocketNumber(docketNum) { if (typeof docketNum !== 'string' || docketNum.length !== 7) { throw new Error('无效的Docket Number格式'); } // 拆分Store编码(前3位)和Transaction编码(后4位) const storeCode = docketNum.slice(0, 3); const transCode = docketNum.slice(3); // 解码StoreId let obfuscatedStore = 0; for (const char of storeCode) { obfuscatedStore = obfuscatedStore * CHAR_SET_LEN + CHAR_SET.indexOf(char); } const storeId = obfuscatedStore - STORE_OFFSET; if (storeId < 0 || storeId > 999) { throw new Error('无效的StoreId'); } // 解码TransactionId let obfuscatedTrans = 0; for (const char of transCode) { obfuscatedTrans = obfuscatedTrans * CHAR_SET_LEN + CHAR_SET.indexOf(char); } const transactionId = obfuscatedTrans - TRANS_OFFSET; if (transactionId < 0 || transactionId > 99999) { throw new Error('无效的TransactionId'); } return { storeId, shopDate: new Date(), // 若需真实交易日期,建议在生成时将日期编码进字符串,此处保留原有逻辑 transactionId }; }
方案优势
- 高防破解性:自定义字符集的进制转换+随机偏移,第三方无法通过简单的数值反转、加减推断规则;32种字符的7位编码有3.4×10¹⁰种组合,远超实际业务的1×10⁸种有效组合,枚举破解成本极高。
- 绝对唯一性:每个StoreId+TransactionId的组合对应唯一的混淆值,转32进制后无重复。
- 极致简洁:固定7位编码,远低于9位限制,用户读取、复制更方便。
- 低输入错误率:剔除易混淆字符,避免用户将0/O、1/I等字符搞混。
额外建议
- 混淆偏移密钥(
STORE_OFFSET、TRANS_OFFSET)建议用随机数生成器生成,不要使用如100、1000这类有规律的数值,进一步提升安全性。 - 若需加入交易日期信息,可调整编码结构(比如用2位表示年份后两位+2位表示日期,剩余3位处理StoreId和TransactionId),确保总长度不超过9位即可。
- 生成编码前必须校验输入范围,避免非法值导致编码异常。
内容的提问来源于stack exchange,提问作者Bipin Raj Sitoula
相关产品推荐
相关产品推荐

