You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:04:53