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