解释Vigenère密码的功能 [英] Explaining functions of Vigenère cipher

查看:189
本文介绍了解释Vigenère密码的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 http://rosettacode.org 上找到了Vigenère密码的以下代码,我想了解一下

i found the following code at http://rosettacode.org for the Vigenère cipher and i would like to undestand it better.

有人可以解释一下函数ordA(a) function(a)做吗?

Could someone explain me what the single lines of code in function ordA(a) and in function(a) do?

function ordA(a) {
  return a.charCodeAt(0) - 65;
}

// vigenere
function vigenere2(text, key, decode) {
  var i = 0, b;
  key = key.toUpperCase().replace(/[^A-Z]/g, '');
  return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {
    b = key[i++ % key.length];
    return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));
  });
}


推荐答案

我不确定那应该是示例代码,但是它主要显示了如何不编程。做出了明智的决定 ,但是显然问题分解,变量命名和文档编制还有很多工作要做。重复的代码,混乱的行,无法解释的代码片段,列表继续。解码是布尔值,但加密的相反是解密不解码。编写此代码是为了了解正在发生的事情;在这方面,它在Rosetta网站上所做的事情令人难以置信。

I'm not sure if that is supposed to be example code, but it mainly shows how not to program. Smart decisions are being made, but obviously the problem decomposition, variable naming and documentation leave a lot to be desired. Repeated code, convoluted lines, unexplained code fragments, the list goes on. Decode is a boolean, but the opposite of encryption is decryption not decoding. This code was made to not understand what is going on; what it does on the Rosetta site is mind-boggling in that respect.

返回英文字母或ABC的索引,假设使用大写字母,则使用0到25而不是1到26(因为您可以使用零索引而不是基于一个索引来进行模块化计算)

returns an index in the English alphabet or ABC, assuming uppercase characters, 0 to 25 instead of 1 to 26 (because you can do modular calculations with zero indexing, not with one based indexing)

return a.charCodeAt(0) - 65;






采用明文或密文的函数定义,a键,它可能小于纯文本,并为一个布尔值,以指示我们是否在编码或解码


function definition that takes a plaintext or ciphertext, a key which may be smaller than the plaintext and a Boolean to indicate if we're encoding or decoding

function vigenere2(text, key, decode) 






纯文本和变量b的索引,


index in plaintext and variable b, which will hold a character of the key for the index

var i = 0, b;






将键转换为大写并删除所有字符


converts the key to uppercase and removed all characters not in the uppercase alphabet as well

key = key.toUpperCase().replace(/[^A-Z]/g, '');






此行显然太长;它将文本转换为大写并再次删除非字母字符


this line is too long obviously; it converts the text to uppercase and removes the non-alphabet characters again

然后使用<$ c $第二个参数中定义的函数替换字符串中的字符c>替换

return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {






使用模运算符以循环方式获取密钥的下一个字符,然后再更新索引


take the next character of the key in round robin fashion, using the modulus operator, update the index afterwards

b = key[i++ % key.length];






这里发生的太多,非常糟糕的程序分解;按执行顺序:


too much going on here, very bad program decomposition; in order of execution:


  • (解码?26-ordA(b):ordA(b)):计算范围内的数字以更新明文字符的索引;使用相反的值进行解密(此处错误地称为解码 )

  • (ordA(a)+(解码?26-ordA(b):ordA(b)))%26 执行加法n加上计算出的数字,减少到0到25​​(即当到达Z时继续A,反之亦然)

  • ((ordA(a)+(decode?26-ordA(b):ordA(b))) %26 + 65)加65,以便使用两个完全虚假的括号将索引转换回大写字符的ASCII索引

  • 最后,从一个字符代码结果,否则+将加而不是串联

  • (decode ? 26 - ordA(b) : ordA(b)): calculate a number in the range to update the index of the plaintext character; use the opposite value for decryption (wrongly called "decoding" here)
  • (ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 perform the addition with the calculated number, reduce to 0 to 25 (i.e. when reaching Z continue with A and vice versa)
  • ((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65) add 65 so the index is converted back into the ASCII index of uppercase characters, using two completely spurious parentheses
  • finally, returns a string from one character code result, otherwise + will be addition instead of concatenation
return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));






嗯,它需要结束


well, it needed to end

  });
}






让我们展示另一种方式使用命名良好的变量,用于重用代码的函数和正则表达式进行编程,这些正则表达式非常需要名称来解释其功能。


Let's show another way of programming this, using well named variables, functions for reused code and regular expressions that badly need a name to explain what they do.

var ALPHABET_SIZE = 'Z'.charCodeAt(0) - 'A'.charCodeAt(0) + 1;

var encrypted = vigenere(false, "B", "Zaphod Breeblebox");
document.body.append('<div>' + encrypted + '</div>');
var decrypted = vigenere(true, "B", encrypted);
document.body.append('<div>' + decrypted + '</div>');

function vigenere(decrypt, key, text) {
    key = toJustUppercase(key);
    text = toJustUppercase(text);
  
    var textOffset = 0;
    // iterate over all characters, performing the function on each of them
    return text.replace(/[A-Z]/g, function(textChar) {
        var keyChar = key[textOffset++ % key.length];
        var cryptedChar = substituteCharacter(decrypt, keyChar, textChar);
        return cryptedChar;
    });
}

function substituteCharacter(decrypt, keyChar, textChar) {
    var keyIndex = charToABCIndex(keyChar);
    if (decrypt) {
        // create the opposite of the encryption key index
        keyIndex = ALPHABET_SIZE - keyIndex;
    }
    
    var textIndex = charToABCIndex(textChar);

    // the actual Vigenere substitution, the rest is just indexing and conversion
    var substitutedIndex = (textIndex + keyIndex) % ALPHABET_SIZE;
      
    var substitutedChar = abcIndexToChar(substitutedIndex);
    return substitutedChar;
}

function toJustUppercase(text) {
    return text.toUpperCase().replace(/[^A-Z]/g, '')
}

function charToABCIndex(charValue) {
    return charValue.charCodeAt(0) - 'A'.charCodeAt(0);
}

function abcIndexToChar(index) {
    return String.fromCharCode(index + 'A'.charCodeAt(0));
}

您说的功能太多了吗?不是,我还没有实现 ord chr vigenereEncrypt viginereDecrypt 使其更易于阅读。

Too many functions you say? Not really, I've not implemented ord and chr, or vigenereEncrypt and viginereDecrypt to make it even easier to read.

这篇关于解释Vigenère密码的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆