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

JavaScript字符加密函数适配任意输入求助:现有代码仅通过指定测试用例

凯撒密码加密函数无法处理字母表循环偏移,求修复方案

问题背景

我写了一个凯撒密码加密函数,需求是对输入的大写字符串按指定偏移量加密,非字母字符保持不变(输入始终为大写,无需处理小写)。代码如下:

function encrypt(str, index) { 
  var encryptedstr = ''; 
  var code = 0; 
  for(var i = 0; i < str.length; i++) { 
    var k = str[i].charCodeAt(); 
    if (k >= 65 && k <= 90) { 
      code = k + index; 
      encryptedstr += String.fromCharCode(code); 
    } else { 
      encryptedstr += str[i]; 
    } 
  } 
  return encryptedstr; 
} 
console.log( encrypt('ABC', 4) );

目前这个代码能通过几个基础测试:

  • 返回类型为字符串
  • encrypt("ABC", 4) 输出 "EFG"
  • encrypt("AB C", 2) 输出 "CD E"
  • encrypt("ABC DEF", 2) 输出 "CDE FGH"

但系统提示"答案需对任意给定输入有效",显然有些边界情况没覆盖到,求解决建议。


问题分析

你的代码现在的核心问题是没有处理字母偏移后超出A-Z范围的循环逻辑。举两个典型的反例:

  • 当输入encrypt('XYZ', 4)时,当前代码会输出]^_(X的ASCII 88+4=92,Y=89+4=93,Z=90+4=94,这些都不是大写字母),但正确结果应该是BCD
  • 如果偏移量是负数,比如encrypt('ABC', -2),当前代码会输出@?A,而正确结果应该是YZA

凯撒密码的核心是在26个字母内循环偏移,而不是直接累加偏移量输出任意ASCII字符,这就是你的代码不满足"任意输入"要求的原因。


修复方案

我们需要通过模运算让偏移后的字母始终落在A-Z范围内,具体步骤是:

  1. 将当前字母的ASCII码转换为0-25的索引(A=0,B=1...Z=25)
  2. 加上偏移量后对26取模(字母表长度)
  3. 处理负数偏移的情况(取模后可能得到负数,需要加26确保非负)
  4. 转换回A-Z的ASCII码(加65)

修改后的代码如下:

function encrypt(str, index) { 
  var encryptedstr = ''; 
  const ALPHABET_LENGTH = 26;
  const A_ASCII = 65; // 'A'的ASCII码
  
  for(var i = 0; i < str.length; i++) { 
    var charCode = str[i].charCodeAt(); 
    if (charCode >= A_ASCII && charCode <= A_ASCII + ALPHABET_LENGTH - 1) { 
      // 转换为0-25的字母索引,计算偏移后的值
      const shiftedIndex = ((charCode - A_ASCII) + index) % ALPHABET_LENGTH;
      // 处理负数偏移的情况,保证索引在0-25之间
      const validIndex = shiftedIndex < 0 ? shiftedIndex + ALPHABET_LENGTH : shiftedIndex;
      encryptedstr += String.fromCharCode(A_ASCII + validIndex); 
    } else { 
      encryptedstr += str[i]; 
    } 
  } 
  return encryptedstr; 
} 

// 测试边界情况验证修复效果
console.log(encrypt('XYZ', 4)); // 输出 BCD(正确)
console.log(encrypt('ABC', -2)); // 输出 YZA(正确)
console.log(encrypt('Z', 26)); // 输出 Z(偏移26等于没偏移,正确)
console.log(encrypt('A!B', 30)); // 输出 E!F(30-26=4,偏移4,正确)

代码说明

  • 用常量ALPHABET_LENGTH和A_ASCII替代硬编码的数字,让代码更易读、易维护
  • 通过charCode - A_ASCII把字母转为0-25的索引,这样偏移后取模26就能实现字母表循环
  • 针对负数偏移的情况,当shiftedIndex为负时,加26转成正的有效索引(比如-2+26=24,对应字母Y)
  • 保留了原有的非字母字符处理逻辑,确保空格、符号等不受影响

这样修改后,你的函数就能处理任意正/负偏移量、任意大写字母输入,完全满足"对任意给定输入有效"的要求。

内容的提问来源于stack exchange,提问作者vishnusaran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:54:46