代码之家  ›  专栏  ›  技术社区  ›  Dann

javascript中的Caesar密码:密码已损坏

  •  1
  • Dann  · 技术社区  · 12 年前

    我正在用javascript构建凯撒密码。它使用一个随机设置的变量 currentkey 作为密码的密钥。它可以是-25到+25之间的数字,跳过0。

    我不明白为什么函数在字符串的开头返回undefined,也不明白为什么它会在字符串持续的时间内翻译同一个字母,甚至不明白为什么这个字母根本没有被翻译。

    var currentkey = 5  //for example
    function convertKey(str) {
        var o_text = str;
        var o_letters = o_text.split("");
        var alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','w','z']
        var c_text, _x = "";
        for (x in o_letters) {
            if (currentkey > 0) {
                _x = alphabet[alphabet.indexOf(x) + currentkey]
            } else {
                _x = alphabet[alphabet.indexOf(x) + (26 - currentkey)]
            }
            c_text = c_text + _x;
        }
        return c_text;
    }
    

    例如,运行 convertKey("example") 退货 undefinedeeeeeee (未定义+“示例”中第一个字母的7倍)。

    6 回复  |  直到 12 年前
        1
  •  3
  •   codeguppy    8 年前

    Caesar密码算法在JavaScript中的实现非常有趣,因为JavaScripts缺乏真正的模运算符。%只是分裂的提醒。阅读此内容 article 了解更多解释。

    然而,您可以很容易地将模定义为自定义函数,然后继续实现凯撒密码,这是一种非常简单的加密形式,原始消息中的每个字母都会向左或向右移动一定数量的位置。

    为了解密消息,我们只需将字母向后移动相同数量的位置。

    例子:

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

    如果移位后一个字母超出了字母范围,则该字母被包裹在字母表中。示例:如果将字母Z移动3个位置,则字母Z变为C。

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

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

    Dn(x)=(x n)模26

    试图在不使用适当的模运算符的情况下在JavaScript中实现此算法将产生不正确的结果,或者产生非常神秘且难以理解的代码。

    通过使用自定义的模函数,代码可以同样地表达数学方程:

    // 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;
    }
    
    // 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;
    }
    

    玩得高兴

    加密一些消息以试用代码。请记住:如果您使用正密钥加密,请使用互补的负密钥对其进行解密。您也可以使用此代码对网络和新闻组中随处可见的ROT13消息进行解码。

    如果您想了解在JavaScript中实现modulo的其他方法,请参阅本文开头提到的文章。

        2
  •  2
  •   SnoringFrog Kent    12 年前

    这个 undefined 是未初始化的结果 c_text 在您尝试将其与连接之前 _x .

    代码只适用于一个字母,因为 alphabet.indexOf(x) 退货 -1 (未找到)。使用时 o_text = "abc" , x 等于0、1和2。因此,中的索引0、1或2 alphabet 不存在(由 -1 结果)。你需要将这些数字与 o_text 通过更改 indexOf(x) indexOf(o_text[x]) 此外,为了防止超出数组的界限,您需要一个模运算来包装大于26的值(我已经使用 alphabet.length 以允许该代码与其他字母一起工作)返回到有效区域中。因此,正确的代码如下(注意:我已经将数组中的“w”按字母顺序移动到了它的正确位置,因为我认为它在您的示例中的位置是错误的,不是故意的):

    var currentkey = 5  //for example
    function convertKey(str) {
        var o_text = str;
        var o_letters = o_text.split("");
        var alphabet = ['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 c_text="", _x = "";
        for (x in o_letters) {
            if (currentkey > 0) {
                _x = alphabet[(alphabet.indexOf(o_letters[x]) + currentkey) % alphabet.length]
            } else {
                _x = alphabet[(alphabet.indexOf(o_letters[x]) + (26 - currentkey)) % alphabet.length]
            }
            c_text = c_text + _x;
        }
        return c_text;
    }
    
    alert(convertKey('abcdefghijklmnopqrstuvwxyz'));
    

    此警报的 fghijklmnopqrstuvwxyzabcde

        3
  •  2
  •   Paul Draper    12 年前

    (1) 您没有在数组中进行迭代 o_letters 正确地

    (2) 你的数组超出了范围。

    for (var i = 0; i < o_letters.length; i++) {
        _x = alphabet[(alphabet.indexOf(o_letters[i]) + currentkey + 26) % 26]
        c_text = c_text + _x;
    }
    

    此外,在您的代码中,您不需要 .split("") 完全

    我会这么做:

    var currentkey = 5  //for example
    function convertKey(str) {
        var ret = '';
        for (var i = 0; i < str.length; i++) {
            ret += String.fromCharCode((str.charCodeAt(i) + currentKey + 26) % 26);
        }
        return ret;          
    }
    

    或者更简洁(但效率较低):

    function convertKey(str) {
        return str.split('').map(function(c) {
           return String.fromCharCode((c.charCodeAt(0) + currentKey + 26) % 26);
        }).join('');       
    }
    
        4
  •  1
  •   coopeu    9 年前

    //在…工作 https://www.freecodecamp.org/challenges/caesars-cipher

    function rot13(str){    
    
    var res = [];
    
    var currentPosition;
    
    var shiftedPosition;
    
    for (var i = 0; i<str.length; i++){
        currentPosition = str.charCodeAt(i);
    
        if (currentPosition<65 || currentPosition>90){
        res.push(String.fromCharCode(currentPosition));
        }
    
        shiftedPosition = str.charCodeAt(i) - 13;
    
        if (currentPosition>=65 && shiftedPosition <65){
        res.push(String.fromCharCode(91-(13-(currentPosition-65))));
        }
    
        if (currentPosition>=78 && currentPosition<=90){
        res.push(String.fromCharCode(shiftedPosition));
        }
      }
    return res.join('');`enter code here`
    }
    
    // Change the inputs below to test
    
    rot13("GUR DHVPX OEBJA QBT WHZCRQ BIRE GUR YNML SBK.");
    
        5
  •  0
  •   mandrei100    7 年前

    这里有一个更简单的答案:

    var rot = {
      'A': 'N',
      'B': 'O',
      'C': 'P',
      'D': 'Q',
      'E': 'R',
      'F': 'S',
      'G': 'T',
      'H': 'U',
      'I': 'V',
      'J': 'W',
      'K': 'X',
      "L": 'Y',
      'M': 'Z',
      'N': 'A',
      'O': 'B',
      'P': 'C',
      'Q': 'D',
      'R': 'E',
      'S': 'F',
      'T': 'G',
      'U': 'H',
      'V': 'I',
      'W': 'J',
      'X': 'K',
      'Y': 'L',
      'Z': 'M',
      ' ': ' ',
      '.': '.',
      '!': '!',
      '?': '?'
    };
    
    // Change the inputs below to test
    rot13("SERR CVMMN!");
    // FREE CODE CAMP
    
    function rot13(str) {
      var index = [];
      for (var key in str) {
        for (var property in rot) {
          if (str[key] === property) {
            index.push(rot[property]);
          }
        }
      }
      return index.join('');
    }
        6
  •  0
  •   ruhui0806    6 年前
    function rot13(str) {
    const alphabet1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY';
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    return str
      .split('')
      .map(function(char) {  
        const pos = alphabet.indexOf(char);
        return pos >=0? alphabet1[pos+13] : char;     
      })
      .join('');
    }
    rot13("SERR PBQR PNZC");
    
      
    
    推荐文章