[英]Explaining functions of Vigenère cipher
我在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));
});
}
我不确定这是否应该是示例代码,但它主要展示了如何不编程。 聪明的决定,正在作出,但很明显的问题分解,变量的命名和文档很不理想了很多。 重复的代码、错综复杂的行、无法解释的代码片段,不胜枚举。 Decode 是一个布尔值,但加密的反面是解密而不是解码。 这段代码是为了不明白发生了什么; 在这方面,它在 Rosetta 网站上所做的事情令人难以置信。
返回英文字母表或 ABC 中的索引,假设为大写字符,0 到 25 而不是 1 到 26(因为您可以使用零索引进行模块化计算,而不是使用基于一个的索引)
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(/[AZ]/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(/[^AZ]/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
以使其更易于阅读。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.