Search code examples
javaperformanceencryptionvigenere

Java vigenere cipher performance issues


I have made a vigenere encryption/decryption program which seems to work as I intended, however running my encryption/decryption on a very large text file (500,000 characters aprox) takes 2-4minutes. I have looked through my code and cannot see what operations might be slowing it down. Anyone have any ideas how I could speed this up?

Code:

public static String encrypt(String text, String key)
{
    String cipherText = "";
    text = text.toLowerCase();
    for(int i = 0; i < text.length(); i++)
    {
        System.out.println("Count: "+ i); //I just put this in to check the 
                                          //loop wasn't doing anything unexpected
        int keyIndex = key.charAt(i%key.length()) - 'a';
        int textIndex = text.charAt(i) - 'a';
        if(text.charAt(i) >= 'a' && text.charAt(i) <= 'z') { //check letter is in alphabet
            int vigenere = ((textIndex + keyIndex) % 26) + 'a';
            cipherText = cipherText + (char)vigenere;
        } else 
            cipherText = cipherText + text.charAt(i);
        }

    }
    return cipherText;
}

Prior to running the encrypt I have a method which reads the text file to a String using Scanner. This String plus a predefined key are used to create the encrypted text.

Thanks.

ANSWER

Thanks to RC - it was my string concatenation taking the time. If anyone else is interested this is my updated code which works quickly now:

public static String encrypt(String text, String key)
{
    StringBuilder cipher = new StringBuilder();
    for(int i = 0; i < text.length(); i++)
    {
        int keyIndex = key.charAt(i%key.length()) - 'a';
        int textIndex = text.charAt(i) - 'a';
        if(text.charAt(i) >= 'a' && text.charAt(i) <= 'z') {
            int vigenere = ((textIndex + keyIndex) % 26) + 'a';
            cipher.append((char)vigenere);
        } else {
            cipher.append(text.charAt(i));
        }

    }
    return cipher.toString();
}

Solution

  • Append to a StringBuilder instead of creating new String instances. You want to do a

    buffer.append((char)vigenere);
    

    instead of a cipherText = cipherText + (char)vigenere;