Java,如何实现移位密码(Caesar Cipher)

时间:2013-10-01 05:38:00

标签: java encryption

我想实现一个Caesar Cipher移位,将字符串中的每个字母增加3。

我收到此错误:

possible loss of precision required char; found int

到目前为止,这是我的代码:

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);               
        }              
    }
}

导致此错误的原因是什么?如何实现caesar Cipher shift以将字符串中的每个字母增加3?

6 个答案:

答案 0 :(得分:11)

Java Shift Caesar Cipher shift空格。

<强>限制:

  1. 仅适用于shift参数中的正数。
  2. 仅适用于班次少于26的人。
  3. 对于超过几千个字符的文本主体,是否会使计算机陷入困境。
  4. 对一个角色进行演员编号,因此除了ascii字母外,它都会失败。
  5. 只容忍字母a到z。无法处理空格,数字,符号或unicode。
  6. 代码违反了DRY(不要重复自己)原则,重复计算的次数超过了它。
  7. <强>伪代码:

    1. 遍历字符串中的每个字符。
    2. 向角色添加移位,如果它从字母表的末尾掉落,则从字母表中的字母数减去移位(26)
    3. 如果班次没有使角色从字母表的末尾掉落,则将班次添加到角色。
    4. 将角色附加到新字符串上。返回字符串。
    5. <强>功能:

      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;
      }
      

      如何调用它:

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

答案 1 :(得分:6)

下面的代码也处理大小写的情况,并保留其他字符。

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();
    }
}

答案 2 :(得分:1)

警告是由于您尝试向字符值添加整数(int shift = 3)。如果您想避免这种情况,可以将数据类型更改为char

char为16位,int为32。

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

顺便说一句,您可以简化以下内容:

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

要:

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

答案 3 :(得分:1)

实施凯撒密码的两种方法:

选项1: 将字符更改为ASCII数字,然后您可以增加该值,然后将其还原为新字符。

选项2:使用地图将每个字母映射到这样的数字。

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

使用地图,您无需每次都重新计算班次。然后,您可以通过以下地图更改为从明文更改为加密。

答案 4 :(得分:0)

您好...我已经为凯撒密码创建了一个Java客户端服务器应用程序...我创建了一个可以正确解密文本的新公式... 对不起只有小写..!

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<en.length())
{
j=cs.indexOf(en.charAt(i));
k=(j+(26-key))%26;
d=d+cs.charAt(k);
i++;
}
while (num < 21)
{
progress.setValue(num);
try {
Thread.sleep(100);
} catch (InterruptedException ex) { }
progress.setValue( num );
Rectangle progressRect = progress.getBounds();
progressRect.x=0;
progressRect.y=0;
progress.paintImmediately( progressRect );
num++;
}
l5.setText("Decrypted text: "+d);
}
}
public static void main(String args[])throws IOException
{
new ceasarserver();
String strm =new String();
ServerSocket
ss=new ServerSocket(4321);
l1.setText("Secure data transfer Server Started....");
Socket s=ss.accept();
l2.setText("Client Connected !");
while(true)
{
Scanner br1= new Scanner(s.getInputStream());
en=br1.nextLine();
l3.setText("Client:"+en);
}
}
}



import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class ceasarclient extends JFrame
{
String cs="abcdefghijklmnopqrstuvwxyz";
static JLabel l1,l2,l3,l4,l5;
JButton b1,b2,b3;
JTextField t1,t2;
JProgressBar progress;
int num=0;
String en="";
ceasarclient(final Socket s)
{
super("CLIENT");
JPanel p=new JPanel(new GridLayout(10,1));
setSize(500,500);
t1=new JTextField(30);
b1=new JButton("Send");
b1.setMnemonic('S');
b2=new JButton("Close");
b2.setMnemonic('C');
l1=new JLabel("Welcome to Secure Data transfer!");
l2=new JLabel("Enter the word here...");
l3=new JLabel("");
l4=new JLabel("Enter the Key:");
b3=new JButton("Encrypt");
b3.setMnemonic('E');
t2=new JTextField(30);
progress = new JProgressBar(0, 20);
progress.setValue(0);
progress.setStringPainted(true);
p.add(l1);
p.add(l2);
p.add(t1);
p.add(l4);
p.add(t2);
p.add(b3);
p.add(progress);
p.add(b1);
p.add(l3);
p.add(b2);
add(p);
setVisible(true);
b1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try{
PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
pw.println(en);
}catch(Exception ex){};
l3.setText("Encrypted Text Sent.");
}
});
b3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String strw=t1.getText();
int key=Integer.parseInt(t2.getText());
int i=0,j,k;
while(i<strw.length())
{
j=cs.indexOf(strw.charAt(
i));
k=(j+key)%26;
en=en+cs.charAt(k);
i++;
}
while (num < 21)
{
progress.setValue(num);
try {
Thread.sleep(100);
} catch (InterruptedException exe) { }
progress.setValue( num );
Rectangle progressRect = progress.getBounds();
progressRect.x=0;
progressRect.y=0;
progress.paintImmediately( progressRect );
num++;
}
}
});
b2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) 
{
System.exit(0);
}
});
pack();
}
public static void main(String args[])throws IOException
{
final Socket s =new Socket(InetAddress.getLocalHost(),4321);
new ceasarclient(s);
}
}

答案 5 :(得分:0)

//我们可以使用char作为整数作为Java将每个字符存储为ascii整数

String rotationCipher(String input, int rotationFactor){

    char [] inputArr = input.toCharArray();

    String resultStr = "";

    for (char ch: inputArr ) {
        if(ch < 58 && ch>48){
            int withRotetionFactor = ch + rotationFactor;
            if(withRotetionFactor < 57){
              resultStr = resultStr + (char) withRotetionFactor;
           }else {
                 int looprotation =  withRotetionFactor - 10;
                resultStr = resultStr + (char)looprotation;
            }
        }else  if(ch < 91 && ch>63){
            int withRotetionFactor = ch + rotationFactor;
            if(withRotetionFactor < 91){
                resultStr = resultStr + (char) withRotetionFactor;
            }else {
                int looprotation =  withRotetionFactor - 26;
                resultStr = resultStr + (char)looprotation;
            }
        }else if(ch < 123 && ch>96){
            int withRotetionFactor = ch + rotationFactor;
            if(withRotetionFactor < 123){
                resultStr = resultStr + (char) withRotetionFactor;
            }else {
                int looprotation =  withRotetionFactor - 26;
                resultStr = resultStr + (char)looprotation;
            }
        }else {
            resultStr = resultStr + ch;
        }



    }
    return resultStr;

}