Java, Cómo implementar un Cifrado de Shift (Cifrado César)

Quiero implementar un cambio de Cifrado César para boost cada letra en una cadena por 3.

Estoy recibiendo este error:

possible loss of precision required char; found int 

Aquí está mi código hasta ahora:

 import java.util.Scanner; import java.io.*; public class CaesarCipher { public static void main (String [] args) { char[] letters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; char[] message = "onceuponatime".toCharArray(); char[] eMessage = new char[message.length]; char shift = 3; //encrypting message for(int i = 0; i <= message.length; ++i) { eMessage[i] = (message[i] + shift) % (char) letters.length; System.out.println(x); } } } 

¿Qué causa este error? ¿Cómo puedo implementar un cambio Cipher César para boost cada letra en una cadena por 3?

Java Shift Caesar Cipher por espacios de shift .

Restricciones

  1. Solo funciona con un número positivo en el parámetro shift.
  2. Solo funciona con turno inferior a 26.
  3. Hace un + = que empantanará la computadora para cuerpos de texto de más de unos pocos miles de caracteres.
  4. Tiene un número de lanzamiento para el personaje, por lo que fallará con cualquier cosa que no sean letras ascii.
  5. Solo tolera las letras aa z. No puede manejar espacios, números, símbolos o unicode.
  6. El código infringe el principio DRY (no se repita) repitiendo el cálculo más de lo necesario.

Pseudocódigo:

  1. Pasa por cada personaje de la cuerda.
  2. Agregue shift al caracter y si se cae al final del alfabeto, restar el desplazamiento del número de letras en el alfabeto (26)
  3. Si el cambio no hace que el personaje caiga al final del alfabeto, entonces agregue el cambio al carácter.
  4. Añade el personaje a una nueva cuerda. Devuelve la cadena.

Función:

 String cipher(String msg, int shift){ String s = ""; int len = msg.length(); for(int x = 0; x < len; x++){ char c = (char)(msg.charAt(x) + shift); if (c > 'z') s += (char)(msg.charAt(x) - (26-shift)); else s += (char)(msg.charAt(x) + shift); } return s; } 

Cómo invocarlo:

 System.out.println(cipher("abc", 3)); //prints def System.out.println(cipher("xyz", 3)); //prints abc 

A continuación, el código maneja las mayúsculas y minúsculas también y deja otro carácter como está.

 import java.util.Scanner; public class CaesarCipher { public static void main(String[] args) { Scanner in = new Scanner(System.in); int length = Integer.parseInt(in.nextLine()); String str = in.nextLine(); int k = Integer.parseInt(in.nextLine()); k = k % 26; System.out.println(encrypt(str, length, k)); in.close(); } private static String encrypt(String str, int length, int shift) { StringBuilder strBuilder = new StringBuilder(); char c; for (int i = 0; i < length; i++) { c = str.charAt(i); // if c is letter ONLY then shift them, else directly add it if (Character.isLetter(c)) { c = (char) (str.charAt(i) + shift); // System.out.println(c); // checking case or range check is important, just if (c > 'z' // || c > 'Z') // will not work if ((Character.isLowerCase(str.charAt(i)) && c > 'z') || (Character.isUpperCase(str.charAt(i)) && c > 'Z')) c = (char) (str.charAt(i) - (26 - shift)); } strBuilder.append(c); } return strBuilder.toString(); } } 

La advertencia se debe a que intenta agregar un entero ( int shift = 3 ) a un valor de carácter. Puede cambiar el tipo de datos a char si quiere evitar eso.

Un char es de 16 bits, un int es 32.

 char shift = 3; // ... eMessage[i] = (message[i] + shift) % (char)letters.length; 

Como un aparte, puedes simplificar lo siguiente:

 char[] message = {'o', 'n', 'c', 'e', 'u', 'p', 'o', 'n', 'a', 't', 'i', 'm', 'e'}; 

A:

 char[] message = "onceuponatime".toCharArray(); 

Dos formas de implementar un cifrado César:

Opción 1: Cambie los caracteres a los números ASCII, luego puede boost el valor y luego revertirlo al nuevo carácter.

Opción 2: Use un Mapa de mapa de cada letra a un dígito como este.

 A - 0 B - 1 C - 2 etc... 

Con un mapa, no tiene que volver a calcular el cambio cada vez. Luego puede cambiar de texto plano a encriptado por el siguiente mapa.

Hola … He creado una aplicación de servidor cliente java en swing para cifrado César … He creado una nueva fórmula que puede descifrar el texto correctamente … lo siento solo por minúsculas …!

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.net.*; import java.util.*; public class ceasarserver extends JFrame implements ActionListener { static String cs="abcdefghijklmnopqrstuvwxyz"; static JLabel l1,l2,l3,l5,l6; JTextField t1; JButton close,b1; static String en; int num=0; JProgressBar progress; ceasarserver() { super("SERVER"); JPanel p=new JPanel(new GridLayout(10,1)); l1=new JLabel(""); l2=new JLabel(""); l3=new JLabel(""); l5=new JLabel(""); l6=new JLabel("Enter the Key..."); t1=new JTextField(30); progress = new JProgressBar(0, 20); progress.setValue(0); progress.setStringPainted(true); close=new JButton("Close"); close.setMnemonic('C'); close.setPreferredSize(new Dimension(300, 25)); close.addActionListener(this); b1=new JButton("Decrypt"); b1.setMnemonic('D'); b1.addAction Listener(this); p.add(l1); p.add(l2); p.add(l3); p.add(l6); p.add(t1); p.add(b1); p.add(progress); p.add(l5); p.add(close); add(p); setVisible(true); pack(); } public void actionPerformed(ActionEvent e) { if(e.getSource()==close) System.exit(0); else if(e.getSource()==b1) { int key=Integer.parseInt(t1.getText()); String d=""; int i=0,j,k; while(i