我正在尝试通过Odin Projects凯撒密码(Caesars Cipher),并且测试要求能够转换负移。根据当前代码,我可以转换小写字母,但是B或W存在一些问题。

it('works with negative shift', function() {
    expect(caesar('Mjqqt, Btwqi!', -5)).toEqual('Hello, World!');


但是返回时我的代码吐出来了


  “你好,=奥尔德!”


很近!我一直在试图找出问题所在,但由于'H'在起作用,所以我不确定自己在做什么错

我已经多次重写了这个东西,而我总是在这里结束。我敢肯定那只是一个数字之遥。但是,这超出了我目前所知道或可以理解的范围。

预先谢谢大家,对于如此简单的问题,我们深表歉意。

const caesar = function(message, shift) {
    return message
    .split("") //splits it into an array
    .map(message => { //does the following to each element in the array
        normalStr = String.fromCharCode(message.charCodeAt())
        prePoint = message.charCodeAt() //gets the charcode of element
    //if/else checks to see if upper or lower case
    if (prePoint >= 65 && prePoint <= 90) { //upper case
        return String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
    } else if (prePoint >= 97 && prePoint <= 122){ //lower case
        return String.fromCharCode((prePoint -97 + shift % 26) + 97)
    }  else {
        return normalStr

        //1 func proc uppoer case
        //1 func proc lowercase
        //1 func proc non upper/lower case
    }})
    .join("")

}

最佳答案

您的代码仅适用于正向凯撒平移,因为
String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
prePoint - 65 + shift可能低于零(如果prePoint = B = 66且shift = -5,您将得到-4

您可以通过检查(prePoint - 65 + shift)的结果是否为负来解决此问题,如果是,则将其添加26:

let newPoint = (prePoint - 65 + shift) % 26;
if(newPoint < 0) newPoint += 26;
return String.fromCharCode(newPoint + 65);


(小写字母相同)

或者,您可以在函数开始时将负移位转换为正移位(-5 caear移位与21 caesar移位相同):

if(shift < 0) { shift = 26 + (shift % 26);}


完整示例:



function caesar(message, shift) {
  if (shift < 0) {
    shift = 26 + (shift % 26);
  }
  return message
    .split("") //splits it into an array
    .map(message => { //does the following to each element in the array
      normalStr = String.fromCharCode(message.charCodeAt())
      prePoint = message.charCodeAt() //gets the charcode of element
      //if/else checks to see if upper or lower case
      if (prePoint >= 65 && prePoint <= 90) { //upper case
        return String.fromCharCode(((prePoint - 65 + shift) % 26) + 65);
      } else if (prePoint >= 97 && prePoint <= 122) { //lower case
        return String.fromCharCode(((prePoint - 97 + shift) % 26) + 97)
      } else {
        return normalStr;
      }
    })
    .join("");
}

console.log(caesar('Mjqqt, Btwqi!', -5)); // Hello World!

07-24 16:28