Pregunta

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();
}
¿Fue útil?

Solución

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;

Otros consejos

At present you are doing

for(int i = 0; i < text.length(); i++){
    ...
    int keyIndex = key.charAt(i%key.length()) - 'a';
    ...
}

You can try to remove the calucation of the keyIndex from the for-loop and realize it in a preprocessing step. For example, you can store the keyIndex values/ characters in a separate array and access the array contents in your original loop. This should save you some calculation steps.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top