i found the following code at http://rosettacode.org for the Vigenère cipher and i would like to undestand it better.
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));
});
}
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.
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)
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
index in plaintext and variable b, which will hold a character of the key for the index
converts the key to uppercase and removed all characters not in the uppercase alphabet as well
this line is too long obviously; it converts the text to uppercase and removes the non-alphabet characters again
then it replaces the characters in the string using the function defined in the second argument of
replace
take the next character of the key in round robin fashion, using the modulus operator, update the index afterwards
too much going on here, very bad program decomposition; in order of execution:
(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 parentheseswell, 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.
Too many functions you say? Not really, I've not implemented
ord
andchr
, orvigenereEncrypt
andviginereDecrypt
to make it even easier to read.