String.fromCharCode()未按预期运行 字符移位解密输出乱码
问题原因
- 乱码的核心诱因有两个:
- 实际运行的解密代码未正确执行减法:从输出字符反推,解密时实际跑的是字符编码和偏移量的加法运算,大概率是改完代码未保存、热更新失效,或是手滑把减号错写为加号。你输出的ϕ(U+03D5,十进制981)、ϟ(U+03DF,十进制991)、ϩ(U+03E9,十进制1001)、ϳ(U+03F3,十进制1011),正好是b(98)、c(99)、d(100)、e(101)的编码和字符串"1"拼接后的数值对应的字符,完全匹配加法+字符串拼接的运算结果。
- 环境变量未做显式类型转换:
process.env读取的所有值默认是字符串类型,你没有把NUMBEROFCHARS转成数字就直接参与运算,当使用+运算符时,数字+字符串会触发字符串拼接而非数值相加,直接生成错误的字符编码。
- 额外隐患:两个函数的
catch块都是空实现,运行时错误会被直接吞掉,根本无法定位问题;另外当前移位逻辑没有做字母边界处理,加密到z/Z时会直接跳到符号区,不会循环回到a/A。
修复方案
- 先确认解密函数里的运算符是减号,保存代码后重新运行,排除代码未生效的低级问题。
- 读取环境变量后显式转为数字类型,禁止依赖JS隐式类型转换。
- 移除空catch块,打印错误信息方便排查问题。
- (可选优化)增加字母边界循环逻辑,保证移位后字符始终在大小写字母区间内。
修复后代码
偏移量初始化
// 提前把环境变量转成数字,做合法性校验 const OFFSET = Number(process.env.NUMBEROFCHARS); if (isNaN(OFFSET)) { throw new Error("NUMBEROFCHARS环境变量必须是合法数字"); }
加密函数
const encryptedInput = (input) => { try { let splitInput = sanitize(input).split(""); let mapped = splitInput.map((element) => { if (element == " ") return element; const code = element.charCodeAt(0); // 小写字母边界处理,z移位后回到a if (code >= 97 && code <= 122) { return String.fromCharCode((code - 97 + OFFSET) % 26 + 97); } // 大写字母边界处理,Z移位后回到A if (code >= 65 && code <= 90) { return String.fromCharCode((code - 65 + OFFSET) % 26 + 65); } // 非字母字符直接偏移 return String.fromCharCode(code + OFFSET); }); return mapped.join(""); } catch (err) { console.error("加密失败:", err); return ""; } };
解密函数
const decryptedInput = (input) => { try { let splitInput = sanitize(input).split(""); let mapped = splitInput.map((element) => { if (element == " ") return element; const code = element.charCodeAt(0); // 小写字母边界处理,a反向移位后回到z if (code >= 97 && code <= 122) { return String.fromCharCode((code - 97 - OFFSET + 26) % 26 + 97); } // 大写字母边界处理,A反向移位后回到Z if (code >= 65 && code <= 90) { return String.fromCharCode((code - 65 - OFFSET + 26) % 26 + 65); } // 非字母字符直接反向偏移 return String.fromCharCode(code - OFFSET); }); return mapped.join(""); } catch (err) { console.error("解密失败:", err); return ""; } };
内容的提问来源于stack exchange,提问作者Fat Fatty
相关产品推荐
相关产品推荐

