Please can someone explain the line of code highlighted below. I don't understand at all how this line works.
You can use this example to help me:
input: ATTACK keyword: LEMON res: LXFOPV
I don't understand how that line helps encode A to L and other letter...
ACSII involvement?
static String encrypt(String text, final String key) {
String res = "";
text = text.toUpperCase();
for (int i = 0, j = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c < 'A' || c > 'Z') continue;
////////////////////////////////////////////////////////////////////////////
//please someone explain this line
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
////////////////////////////////////////////////////////////////////////
j = ++j % key.length();
}
return res;
}
The keyword of a Vigenère cipher describes the rotation among the Caesar cipher alphabets that are used. That rotation leads to patterns that can be exploited by a cryptanalyst. If we know the length of the keyword, we can often determine the keyword and, hence, decrypt all messages encrypted with that keyword.
For example, in a Caesar cipher of shift 3, a would become D , b would become E , y would become B and so on. The Vigenère cipher has several Caesar ciphers in sequence with different shift values. To encrypt, a table of alphabets can be used, termed a tabula recta, Vigenère square or Vigenère table.
The code uses the ASCII value of the letters. The letters A-Z are ASCII values 65-90.
The idea is to add the two letters together, but wrap around if the values goes above 90 (known as modular arithmetic). So 91 should actually be 65 (i.e. Z + 1 = A).
Java provides a % operator for doing modular arithmetic (x % n). However, this is designed to work on a range of numbers 0→n-1. So, if we subtract 65 from each of our letters, we are then working in the range 0→25. This allows us to use the modulus operator (x % 26).
This is what the code is doing:
c + key.charAt(j) - 2 * 'A'
This part adds the two letters together, but also subtracts 65 from each of them. It may be easier to understand if written as:
(c - 'A') + (key.charAt(j) - 'A')
You'll notice that you can do - 'A' as a convenient way of doing - 65.
Now we have a value that's zero-based, but possibly larger than 25. So we then modulo it:
(c + key.charAt(j) - 2 * 'A') % 26
We then need to add 65 back to the value, to bring it back into the A-Z range for ASCII:
(c + key.charAt(j) - 2 * 'A') % 26 + 'A'
The only remaining step is to cast this to a char, since the result is an int by default:
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
If the input is ATTACK and the keyword is LEMON, then at some point we are going to have to consider the input letter T (ASCII 84) and the key letter M (ASCII 77).
Subtracting 65 from each, we have T=19 and M=12. Added together, we get 31.
31 % 26 = 5. So we then calculate 5+65=70, which is the ASCII value for F.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With