簡體   English   中英

javascript中的凱撒密碼:密碼被破壞

[英]Caesar Cipher in javascript: cipher broken

我正在用 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 (未定義 + "example" 中第一個字母的 7 倍)。

由於 JavaScript 缺少真正的模運算符,因此在 JavaScript 中實現 Caesar Cipher 算法非常有趣。 % 只是除法的提醒。 閱讀這篇文章以獲得更多解釋。

但是,您可以輕松地將模定義為自定義函數,然后繼續實現凱撒密碼——這是一種非常簡單的加密形式,其中原始消息中的每個字母向左或向右移動某個職位數。

要解密消息,我們只需將字母移回相同數量的位置。

例子:

  • 如果我們將所有字母移動 3 個位置,JAVASCRIPT 將變成 MDYDVFULSW
  • 如果我們將所有字母向后移動 3 個位置,MDYDVFULSW 將返回 JAVASCRIPT。

如果移位后一個字母超出了字母范圍,則該字母將在字母表中環繞。 示例:如果字母 Z 移動 3 個位置,則變為 C。

這種“環繞”效果意味着使用模數。 用數學術語來說,上面的可以表示為:

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

Dn(x) = (x – n) mod 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 中實現取模的其他方法,請參閱本文開頭提到的文章。

(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('');       
}

undefined是在嘗試將c_text_x連接之前未初始化的結果。

該代碼僅適用於一個字母,因為alphabet.indexOf(x)返回-1 (未找到)。 使用o_text = "abc"x等於 0、1 和 2。因此, alphabet的 0、1 或 2 索引不存在(由-1結果指示)。 您需要通過將indexOf(x)更改為indexOf(o_text[x])將這些數字關聯回o_text 此外,為了防止超出數組的范圍,您需要一個模數運算來將大於 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

// 在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.");

這是一個更簡單的答案:

 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(''); }

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");

  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM