Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about Vigenère cipher implementation in Java

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;
}
like image 555
JavaBeginner Avatar asked Feb 26 '15 08:02

JavaBeginner


People also ask

How do you identify a vigenere cipher?

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.

What is vigenere cipher explain with example?

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.


1 Answers

Background

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'); 

Example

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.

like image 171
Duncan Jones Avatar answered Sep 30 '22 10:09

Duncan Jones