Implementação de cifra Scytale (criptografia e descriptografia)

Sep 08 2020

Este é o exercício da web 3.1.41. do livro Computer Science An Interdisciplinary Approach, de Sedgewick & Wayne:

A cifra scytale é um dos primeiros dispositivos criptográficos usados ​​para fins militares. (Veja o livro de códigos .) Foi usado pelos espartanos no quinto século AEC. Para embaralhar o texto, você imprime cada k-ésimo caractere começando no início, a seguir todo k-ésimo caractere começando no segundo caractere e assim por diante. Escreva um programa que implemente esse esquema de criptografia.

Aqui está o meu programa:

public class ScytaleCipher 
{
    public static String encrypt(String text, int kth)
    {
        int textLength = text.length();
        String encrypted = "";
        for (int i = 0; i < kth; i++)
        {
            for (int j = 0; i+j < textLength; j += kth)
            {
                encrypted += String.valueOf(text.charAt(i+j));
            }
        }
        return encrypted;
    }
    public static String decrypt(String text, int kth)
    {
        return encrypt(text, kth-1);
    }
    public static void main(String[] args)
    {
        int kth = Integer.parseInt(args[0]);
        String message = "";
        while (!StdIn.isEmpty())
        {
            String word = StdIn.readString();
            message += word;
        }
        // to encrypt
        System.out.println(encrypt(message, kth));
        // to decrypt
        //System.out.println(decrypt(message, kth));
    }
}

StdIn é uma API simples escrita pelos autores do livro. Verifiquei meu programa e funciona.

Existe alguma maneira de melhorar meu programa?

Agradecimentos para sua atenção.

Respostas

2 Doi9t Sep 08 2020 at 04:35

Tenho algumas sugestões para o seu código.

Use java.lang.StringBuilderpara concatenar String em um loop.

Geralmente é mais eficiente usar o construtor em um loop, uma vez que o compilador não é capaz de otimizá-lo sozinho enquanto traduz seu código em bytecode; O compilador não usará java.lang.StringBuilderloops complexos e seu método levará mais tempo e mais memória para ser executado, já que o String Object é imutável (uma nova instância será criada a cada iteração).

StringBuilder encrypted = new StringBuilder();
for (int i = 0; i < kth; i++) {
   for (int j = 0; i + j < textLength; j += kth) {
      encrypted.append(text.charAt(i + j));
   }
}
return encrypted.toString();

Ao concatenar um primitivo em uma string, você não precisa convertê-lo.

Você pode adicionar a primitiva (int, double, float, char, ect) diretamente na string usando os operadores de atribuição (+, + =).

Antes

encrypted += String.valueOf(text.charAt(i+j));

Após

encrypted += text.charAt(i+j);