我在http://rosettacode.org处发现了Vigenère密码的以下代码,我想更好地理解它。
有人可以解释一下function ordA(a)
和function(a)
中的单行代码是做什么的吗?
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));
});
}
答案 0 :(得分:0)
我不确定这是否应该是示例代码,但是它主要显示了如何不编程。可以做出明智的决定,但显然问题分解,变量命名和文档编制还有很多工作要做。重复的代码,混乱的行,无法解释的代码片段,列表继续。解码是布尔值,但加密的相反是解密不解码。编写此代码是为了不了解正在发生的事情;在这方面,它在Rosetta网站上所做的事情令人难以置信。
以大写字母返回0到25而不是1到26来返回英文字母或ABC的索引(因为您可以使用零索引而不是基于一个索引来进行模块化计算)
return a.charCodeAt(0) - 65;
采用明文或密文的函数定义,可能小于明文的密钥,以及表示我们正在编码还是解码的布尔值
function vigenere2(text, key, decode)
纯文本索引和变量b,将保留索引键的字符
var i = 0, b;
将键转换为大写字母,并删除所有不在大写字母中的字符
key = key.toUpperCase().replace(/[^A-Z]/g, '');
此行显然太长;它将文本转换为大写并再次删除非字母字符
然后使用replace
的第二个参数中定义的函数替换字符串中的字符
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {
以循环方式获取密钥的下一个字符,使用模运算符,然后更新索引
b = key[i++ % key.length];
这里发生了太多事情,程序分解非常糟糕;按执行顺序:
(decode ? 26 - ordA(b) : ordA(b))
:计算范围内的数字以更新明文字符的索引;使用相反的值进行解密(此处错误地称为“解码”)(ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26
用计算出的数字执行加法,减少到0到25(即,当到达Z时继续按A,反之亦然)((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65)
加65,以便使用两个完全虚假的括号将索引转换回大写字符的ASCII索引return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));
好吧,它需要结束
});
}
让我们展示另一种编程方法,使用命名变量,重用代码的函数和正则表达式,这些表达式急需一个名称来解释其功能。
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
来使其更易于阅读。