JavaScript字符串编解码失真问题排查与修复求助
问题分析与修复方案
你的代码存在几个关键问题,直接导致字符串失真:
1. splitIntoChunks 函数未填充结果数组
函数内创建了chunk变量,但未将其添加到chunks数组中,返回空数组后会导致解码时无法正确拆分数据。
2. 超长数字转换时的精度丢失
encode函数中,你将newNumberArray拼接成字符串后用parseInt转换,再转BigInt。但parseInt处理超长数字时会丢失精度(JavaScript普通数字仅能精确表示到2^53),直接破坏原始数据。
3. 解码时的拆分逻辑错误
你固定用chunkSize=2拆分数字字符串,但10 + charCodeAt(0)的结果可能是3位数(比如charCode为255时,10+255=265),固定拆2位会导致后续字符解码错误。
4. 解码遗漏URI反解码
编码时对字符串做了encodeURIComponent,但解码最后未做对应的反解码操作,无法还原原始字符串。
修复后的完整代码
function splitIntoChunks(str, chunkSize) { let chunks = []; for (let i = 0; i < str.length; i += chunkSize) { let chunk = str.slice(i, i + chunkSize); chunks.push(chunk); // 修复:将chunk添加到结果数组 } return chunks; } function stringToNumber(string, bool) { let num = BigInt(0); const base = BigInt(1103871); for (let i = 0; i < string.length; i++) { num = num * base + BigInt(string.charCodeAt(i)); } if (bool) { console.log(string); console.log(numberToString(num, false)); } return num; } function numberToString(number, bool) { let str = ''; const base = BigInt(1103871); let num = number; while (num > 0) { const charCode = Number(num % base); str = String.fromCharCode(charCode) + str; num = num / base; // BigInt除法自动取整,符合需求 } if (bool) { console.log(number); console.log(stringToNumber(str, false)); } return str; } function encode(string) { const encodedString = encodeURIComponent(string); let bigNumStr = ''; // 直接拼接成BigInt兼容字符串,避免parseInt精度丢失 for (const char of encodedString) { bigNumStr += (10 + char.charCodeAt(0)).toString(); } const bigNum = BigInt(bigNumStr); return encodeURIComponent(numberToString(bigNum, true)); } function decode(string) { const weirdUnicodeCharacters = decodeURIComponent(string); const numStr = stringToNumber(weirdUnicodeCharacters, true).toString(); let resultString = ""; let i = 0; // 动态拆分:兼容2位或3位数字(10+charCode范围为10-265) while (i < numStr.length) { if (i + 3 <= numStr.length) { const threeDigit = parseInt(numStr.slice(i, i+3)); if (threeDigit >= 10 && threeDigit <= 265) { resultString += String.fromCharCode(threeDigit - 10); i += 3; continue; } } const twoDigit = parseInt(numStr.slice(i, i+2)); resultString += String.fromCharCode(twoDigit - 10); i += 2; } return decodeURIComponent(resultString); // 修复:添加URI反解码 } // 测试 console.log(encode("Hello world!")); console.log(decode(encode("Hello world!"))); // 现在会输出正确的"Hello world!"
额外优化点
- 提取重复使用的基数
1103871为常量,避免硬编码错误 - 编码时直接拼接数字字符串,跳过数组转换,提升效率
- 解码采用动态拆分逻辑,兼容2位和3位的数字情况
内容的提问来源于stack exchange,提问作者user20479204
相关产品推荐
相关产品推荐

