Javascript中的凯撒密码

时间:2017-05-28 22:33:49

标签: javascript caesar-cipher

我正在尝试编写一个程序来解决javascript中的以下问题(本段下面写着)。我不知道为什么我的代码不起作用。有人能帮助我吗?我是javascript的新手;这是一个免费的代码阵营问题。

"一种常见的现代用途是ROT13密码,其中字母的值移动了13个位置。因此' A' ↔' N',' B' ↔' O'等等。

编写一个函数,该函数将ROT13编码的字符串作为输入并返回已解码的字符串。"



function rot13(str) { // LBH QVQ VG!
  
  var string = "";
  for(var i = 0; i < str.length; i++) {
    var temp = str.charAt(i);
    if(temp !== " " || temp!== "!" || temp!== "?") {
       string += String.fromCharCode(13 + String.prototype.charCodeAt(temp));
    } else {
      string += temp;
    }
  }
  
  return string;
}

// Change the inputs below to test
console.log(rot13("SERR PBQR PNZC")); //should decode to "FREE CODE CAMP"
&#13;
&#13;
&#13;

8 个答案:

答案 0 :(得分:1)

2020 TypeScript版本:

  • 必须提供shift自变量,但是您可以为rot13或其他任何数字选择13
// TypeScript Type: Alphabet
type Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

// Helper Function: Caesar Cipher
export const caesarCipher = (string: string, shift: number) => {
  // Alphabet
  const alphabet: Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

  // Encoded Text
  let encodedText: string = '';

  // Adjust Shift (Over 26 Characters)
  if (shift > 26) {
    // Assign Remainder As Shift
    shift = shift % 26;
  }

  // Iterate Over Data
  let i: number = 0;
  while (i < string.length) {
    // Valid Alphabet Characters
    if (alphabet.indexOf(string[i]) !== -1) {
      // Find Alphabet Index
      const alphabetIndex: number = alphabet.indexOf((string[i]).toUpperCase());

      // Alphabet Index Is In Alphabet Range
      if (alphabet[alphabetIndex + shift]) {
        // Append To String
        encodedText += alphabet[alphabetIndex + shift];
      }
      // Alphabet Index Out Of Range (Adjust Alphabet By 26 Characters)
      else {
        // Append To String
        encodedText += alphabet[alphabetIndex + shift - 26];
      }
    }
    // Special Characters
    else {
      // Append To String
      encodedText += string[i];
    }

    // Increase I
    i++;
  }

  return encodedText;
};

示例1:

console.log(caesarCipher('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 2));

Output:
CDEFGHIJKLMNOPQRSTUVWXYZAB

示例2:

console.log(caesarCipher('GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.', 26 + 13));

Output:
THE QUICK BROWN DOG JUMPED OVER THE LAZY FOX.

答案 1 :(得分:1)

使用模数运算符;使句子大写;

function cipherRot13(str) {
  str = str.toUpperCase();
  return str.replace(/[A-Z]/g, rot13);

  function rot13(correspondance) {
    const charCode = correspondance.charCodeAt();
    //A = 65, Z = 90
    return String.fromCharCode(
            ((charCode + 13) <= 90) ? charCode + 13
                                    : (charCode + 13) % 90 + 64
           );
    
  }
}

答案 2 :(得分:1)

我试图让它变得简单,我赢得了免费 PIZZA!。检查我的解决方案。

    function rot13(str) {
    
    var alphabets =['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'," ", "-", "_", ".", "&","?", "!", "@", "#", "/"];
    
    var alphabets13 = ['N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M', " ", "-", "_", ".", "&","?", "!", "@", "#", "/"];
    
    var resultStr = [];
    for(let i=0; i<str.length; i++){
        for(let j =0; j<alphabets.length; j++){
            if(str[i] === alphabets[j]){
            resultStr.push(alphabets13[j]);
            }
        }
    }
    return resultStr.join("");
  };

  rot13("SERR CVMMN!");

答案 3 :(得分:0)

您可以直接为ROT13构建算法...或者只使用具有相应密钥的Caesar Cipher算法。

我向你的例子提出的另一种选择只是常规凯撒密码算法的一种特殊用法 - 一种非常简单的加密形式,其中原始消息中的每个字母都向左或向右移动一定的职位数。

要解密消息,我们只需将字母移回相同数量的位置。

示例:

  • 如果我们将所有字母移动3个位置
  • ,则JAVASCRIPT变为MDYDVFULSW
  • 如果我们将所有字母移回3个位置,MDYDVFULSW将返回JAVASCRIPT。

如果在移动字母超出字母范围后,则字母会以字母顺序包裹。示例:如果移位3个位置,则字母Z变为C.

这种“环绕”效果意味着使用模数。在数学术语中,上述内容可以表示为:

En(x)=(x + n)mod 26

Dn(x)=(x - n)mod 26

尝试在JavaScript中实现此算法而不使用正确的模运算符将产生不正确的结果或非常神秘且难以理解的代码。

最大的问题是JavaScript不包含模运算符。 %运算符只是对除法的提醒 - 不是模数。但是,将模数作为自定义函数实现非常容易:

// Implement modulo by replacing the negative operand 
// with an equivalent positive operand that has the same wrap-around effect
function mod(n, p)
{
    if ( n < 0 )
        n = p - Math.abs(n) % p;

    return n % p;
}

还有其他实现模数的方法......如果您有兴趣,可以查阅article

通过使用上面定义的mod函数,代码表示相同的数学方程:

// Function will implement Caesar Cipher to
// encrypt / decrypt the msg by shifting the letters
// of the message acording to the key
function encrypt(msg, key)
{
    var encMsg = "";

    for(var i = 0; i < msg.length; i++)
    {
        var code = msg.charCodeAt(i);

        // Encrypt only letters in 'A' ... 'Z' interval
        if (code >= 65 && code <= 65 + 26 - 1)
        {
            code -= 65;
            code = mod(code + key, 26);
            code += 65;
        }

        encMsg += String.fromCharCode(code);
    }

    return encMsg;
}

使用ROT13进行编码...现在只需选择算法名称所示的相应密钥即可。

答案 4 :(得分:0)

const rot13 = (string) => {
//  creating *letterBox* - string in alphabetic way
  const letterBox = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// declaring *iter function* - that will pass through the text 
  const iter = (str, acc) => {   
// if length of string is 0 (phrase is empty) => returning *accumulator*
      if (str.length===0) { return acc; }
/* if is not an uppercase character => calling *function iter* by itself 
with the new string minus first letter and adding to *accumulator*
without coding symbol */ 
      if (! /^[A-Z]*$/.test(str[0])) {return iter(str.substring(1), acc+str[0]); };
// and now we loop through the uppercase letters (26 letters)
//checking their index in our *letterBox*
// if it's more that 13 , we add 13 , else we substract 13 and   
// and of course... calling *iter function* with new string minus first character 
// plus *accumumator* 
     for (let i=0; i<26;i++)
     {
       if ( (letterBox[i]===str[0]) && (i>12))
       { return iter(str.substring(1), acc + letterBox[i-13]); }
       if ( (letterBox[i]===str[0])&& (i<13))
       { return  iter(str.substring(1), acc + letterBox[i+13]); };
      };
  };
 // calling *iter function* with the provided *string* and empty *accumulator*    
 return iter(string,'');
};
   console.log(rot13('GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT.'));
// THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.

通过了Codecamp的成功测试。 也有另一个版本..没有 iter函数



const rot13=(str) =>
{
    var alph= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let result ='';
    while(str.length>0)
  {

  for (let i=0;i<=25;i++)
     { 
       if ((alph[i]===str[0]) && (i>13)) {result = result + alph[i-13];};
       if ((alph[i]===str[0]) && (i<13)) {result = result + alph[i+13] ;} ;
      };
 if (!  /^[A-Z]*$/.test(str[0]) ) {result = result+ str[0];}; 
str=str.substring(1);
   };   
  return result;          
};

console.log(rot13('SERR YBIR?'));
// returns FREE LOVE?

答案 5 :(得分:0)

我最近正处于开发javascript库以简化日常编程要求的第一阶段。 其中之一是加密

该库目前使用凯撒加密。

您可以在开发的早期阶段download缩小版本,并在html页面中将其用作:

d(window).loaded(function() {

  /* *
   * Tidy up the heading
   * */
  d("h1")
    .background("#fafafa")
    .color("orange");

  /* *
   * Encrypt all paragraphs and maximize the height so we view each paragraph separately
   * */
  d("p")
    .encrypt(text = "", depth = 15)
    .resize("60%", "50px");

  /* *
   * Show up the first paragraph element's html
   * */
  _.popUp("First Paragraph: <hr>" + dom("p").getText(), "", "purple")
})

/* *
 * Show the inputed text in below snippet
 * */
function showEncryptedText(){
    d("#encrypted")
    .encrypt(d("#plain").c[0].value, 15)
    .background("#e8e8e8")
    .resize("100%", "100px");

}
<!DOCTYPE HTML>
<html>

<head>
  <title>Element Encryption</title>
  <script type="text/javascript" src="http://codenug.com/libraries/dom.min.js"></script>
</head>

<body>
  <h1>Javascript Encryption</h1>

  <p>This is the first paragraph you may encrypt</p>
  <p>This is another paragraph you may encrypt</p>
  <p>You may encrypt this too</p>
  <h2>You may even provide your text to be encrypted</h2>
  <div id="encrypted">
  
  </div>
  
  <input type="text" id="plain" value="" name="mydata" oninput="showEncryptedText()"/>
  </div>

  <footer>
    <!--- you may place your js here --->
    <script type="text/javascript">
    </script>
</body>

</html>

答案 6 :(得分:0)

我最近刚刚解决了一个凯撒密码算法问题,它的工作原理与您的 rot13 类似,但将采用任何整数值作为移位参数。我注意到您的代码的问题之一是您已经通过为 'i' 处的字符分配 charCode 来将 temp 分配为一个数字。这会使您的条件过时,因为它永远不会识别字符串值,因为您正在传递一个数字值。此外,当您构建字符串时,它应该只是“String.fromCharCode(13 + temp)”。我个人更喜欢凯撒密码,因为您可以分配随机移位参数。

这是我如何编写它的示例:

// s = string to encrypt, k = shift value
// s = 'SERR PBQR PNZC' and k = 13 will produce 'FREE CODE CAMP'
const caesarCipher = function(s, k) {
  let result = '';
  
  for (let i = 0; i < s.length; i++) {

    let charCode = s[i].charCodeAt();
    // check that charCode is a lowercase letter; automatically ignores non-letters
    if (charCode > 96 && charCode < 123) {
      
      charCode += k % 26 // makes it work with numbers greater than 26 to maintain correct shift
      // if shift passes 'z', resets to 'a' to maintain looping shift
      if (charCode > 122) {
        charCode = (charCode - 122) + 96;
      // same as previous, but checking shift doesn't pass 'a' when shifting negative numbers
      } else if (charCode < 97) {
        charCode = (charCode - 97) + 123;
      }
    }

    if (charCode > 64 && charCode < 91) {
      
      charCode += k % 26
      
      if (charCode > 90) {
        charCode = (charCode - 90) + 64;
      } else if (charCode < 65) {
        charCode = (charCode - 65) + 91;
      }
    }

    result += String.fromCharCode(charCode);
  }
  return result
}

答案 7 :(得分:-1)

虽然A + 13可能等于N,但Z + 13将无法正确计算。