Cifrado César en Java

Programa para codificar o decodificar un texto utilizando el método de cifrado de César. Supondremos que el texto solo contiene letras mayúsculas o minúsculas. La letras serán las correspondientes al alfabeto inglés (26 caracteres, excluimos la ñ y Ñ).
En este método de cifrado cada letra del texto se sustituye por otra letra que se encuentra N posiciones adelante en el alfabeto. Se considera que el alfabeto es circular, es decir, la letra siguiente a la ‘z’ es la ‘a’.
Por ejemplo, si N es 3, la ‘a’ se transformaría en ‘d’, la ‘b’ en ‘e’, la ‘c’ en ‘f’, etc.


Ejemplo de cifrado César: si el texto es “casa” y N = 3 el texto cifrado es “fdvd”

Para descifrar un texto se realiza la operación contraria. Se calcula la letra que está N posiciones por detrás en el alfabeto. Como el alfabeto es circular, la letra anterior a la ‘a’ es la ‘z’.

El programa pedirá por teclado un texto, a continuación el valor de N y si queremos codificar o decodificar el texto. Finalmente se mostrará el texto resultante.

Programa resuelto: Cifrado César en Java

import java.io.IOException;
import java.util.Scanner;

public class CifradoCesar {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        String texto;
        int codigo;
        char opcion;
        //Introducir un texto
        do {
            System.out.print("Introduce un texto: ");
            texto = sc.nextLine();
        } while (texto.isEmpty());
        //Introducir el valor del desplazamiento
        do {
            System.out.print("Introduce el código: ");
            codigo = sc.nextInt();
        } while (codigo < 1);
        //Introducir la operación a realizar: cifrar o descifrar
        do {
            sc.nextLine();
            System.out.print("(C) cifrar o (D) descifrar?: ");
            opcion = (char) System.in.read();
        } while (Character.toUpperCase(opcion) != 'C' && Character.toUpperCase(opcion) != 'D');                   
        if (Character.toUpperCase(opcion) == 'C') {
            System.out.println("Texto cifrado: " + cifradoCesar(texto, codigo));
        } else {
            System.out.println("Texto descifrado: " + descifradoCesar(texto, codigo));
        }
    }

    //método para cifrar el texto
    public static String cifradoCesar(String texto, int codigo) {
        StringBuilder cifrado = new StringBuilder();
        codigo = codigo % 26;
        for (int i = 0; i < texto.length(); i++) {
            if (texto.charAt(i) >= 'a' && texto.charAt(i) <= 'z') {
                if ((texto.charAt(i) + codigo) > 'z') {
                    cifrado.append((char) (texto.charAt(i) + codigo - 26));
                } else {
                    cifrado.append((char) (texto.charAt(i) + codigo));
                }
            } else if (texto.charAt(i) >= 'A' && texto.charAt(i) <= 'Z') {
                if ((texto.charAt(i) + codigo) > 'Z') {
                    cifrado.append((char) (texto.charAt(i) + codigo - 26));
                } else {
                    cifrado.append((char) (texto.charAt(i) + codigo));
                }
            }
        }
        return cifrado.toString();
    }

    //método para descifrar el texto
    public static String descifradoCesar(String texto, int codigo) {
        StringBuilder cifrado = new StringBuilder();
        codigo = codigo % 26;
        for (int i = 0; i < texto.length(); i++) {
            if (texto.charAt(i) >= 'a' && texto.charAt(i) <= 'z') {
                if ((texto.charAt(i) - codigo) < 'a') {
                    cifrado.append((char) (texto.charAt(i) - codigo + 26));
                } else {
                    cifrado.append((char) (texto.charAt(i) - codigo));
                }
            } else if (texto.charAt(i) >= 'A' && texto.charAt(i) <= 'Z') {
                if ((texto.charAt(i) - codigo) < 'A') {
                    cifrado.append((char) (texto.charAt(i) - codigo + 26));
                } else {
                    cifrado.append((char) (texto.charAt(i) - codigo));
                }
            }
        }
        return cifrado.toString();
    }
} //Fin cifrado Cesar
Ejemplos de ejecución:

Introduce un texto: Tengo el examen resuelto                                                                      
Introduce el código: 4
(C) cifrar o (D) descifrar?: C
Texto cifrado: Xirksipibeqirviwyipxs

Introduce un texto: glgtekekqutguwgnvqu                                                                           
Introduce el código: 2
(C) cifrar o (D) descifrar?: D
Texto descifrado: ejerciciosresueltos

20 comentarios:

  1. Enrique buenas muy bueno el blog. Queria consultarte en que casos en el main hay que usar el "throws IOException". Saludos

    ResponderEliminar
    Respuestas
    1. Hola Cristian, disculpa por tardar en responder...
      En main o en cualquier método hay que utilizar el "throws IOException" cuando dentro del método hay una instrucción que lanza una IOException, en este ejemplo la instrucción es System.in.read() para leer un carácter:
      opcion = (char) System.in.read();
      La excepción IOException es una excepción marcada y estamos obligados a tratarla, es decir, debemos escribirla dentro de un try..catch o declararla mediante el throws en la cabecera del método.
      En esta entrada del blog se explican las excepciones:
      http://puntocomnoesunlenguaje.blogspot.com.es/2014/04/java-excepciones.html

      Un saludo y gracias por seguir el blog

      Eliminar
    2. Hola Enrique me podrías ayudar a hacer un proyecto de escuela de encriptar y desencriptar frase hola mundo usando y crear una clase con palabra clave te agradecería que me ayudaras todo es en java saludos gracias

      Eliminar
  2. Hola Enrique una pregunta, si ademas de letras tambien se cifran numeros, que se le agregaria?

    ResponderEliminar
  3. Que se tiene que hacer para añadir las letras ñ y Ñ???

    ResponderEliminar
  4. Hermano como podria hacer para que al descifrar, lo haga respetando el espacio de separacion entre palabras? Muy buen blog por cierto.

    ResponderEliminar
  5. Bueno para comprender este ejercicio y como se hacen las operaciones, añadir que que cada letra en el abecedario tiene un código numérico asignado en ASCII

    A = 65
    B = 66
    C ....
    Z = 90

    Y lo mismo sucede con las letras en minúsculas, la diferencia es que el intervalo es ahora de 97 al 122, siendo:
    a = 97
    b = 98
    c...
    z = 122

    ResponderEliminar
  6. Hola Enrique, primero muchas gracias la explicacion de cifrado cesar pero tengo una pregunta, como puedo hacer cuando el usuario ingrese su contraseña el codigo la cifre y cuando intente iniciar sesion la pueda validar se puede hacer?

    ResponderEliminar
  7. como le hago para que me acepte números negativos y la ñ

    ResponderEliminar
  8. Excelente aporte, muchas gracias por compartirlo. Un saludo

    ResponderEliminar
  9. gracias por tu aporte, sin empbargo tengo una duda por que esto: codigo = codigo % 26; gracias.

    ResponderEliminar
    Respuestas
    1. Eso se supone que es para el caso de que si pones por ejemplo 27 seria como haber dado una vuelta completa del abecedario y con el % (modulo) se podria sacar si da 1 es por q ha dado un avuelta completa del abecedario, pero esta sin terminar por que le faltarian unas condiciones para ajustar que se repita el abecedario, a mi me fallaba eso y al comentarlo me va perfecto. Ademas si quisieras que haga lo que acabo de decir tendria que hacer que el resto de esa operacion del modulo sea la posicion x de la nueva vuelta en el abecedario.

      Eliminar
  10. HOLA!!, mi duda tambien es porque esto: codigo = codigo % 26; gracias.

    ResponderEliminar
    Respuestas
    1. Hola, el modular por el valor 26, por lo que sé es por el alfabeto sin contar la ñ, en este caso sería algo como
      A -> 1
      B -> 2
      ...
      Z -> 26
      Entonces utiliza eso para poder desplazar el código.

      Eliminar
  11. Les dejo mi codigo de cifrado cesar, asi admite numeros y respeta los espacios

    public String cifrado(String palabra,int key){
    String result="";
    int aux;
    for(int i=0;i<palabra.length();i++)
    {
    aux=(int) palabra.charAt(i);
    aux=aux+key;

    aux-=48;
    aux=aux%75;
    aux+=48;
    result+=(char) aux;
    }
    return(result);

    }
    public String decifrar(String palabra, int key)
    {
    String result="";
    int aux;
    for(int i=0;i<palabra.length();i++)
    {
    aux=(int) palabra.charAt(i);
    aux=aux-key;
    aux-=48;
    aux=aux%75;
    aux+=48;
    result+=(char) aux;
    }
    return result;
    }
    }

    ResponderEliminar
  12. wow es excelente, llevo todo el dia viendo este maravilloso blog, es super detallado y preciso. Gracias por los programas ojalá agregues para otros lenguajes proximamente

    ResponderEliminar
  13. porque cuando quiero descifrar aparece codigo cifrado?

    ResponderEliminar
    Respuestas
    1. tal vez porque le falta la clave que tiene que ser la misma que la de la frase que cifraste

      Eliminar