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

Sop*_*Ali 5 java encryption

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

我收到此错误:

possible loss of precision required char; found int
Run Code Online (Sandbox Code Playgroud)

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

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);               
        }              
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ski 11

Java Shift Caesar Cipher的shift空格.

限制:

  1. 仅适用于shift参数中的正数.
  2. 仅适用于低于26的班次.
  3. a + =会使计算机陷入长度超过几千个字符的文本体中.
  4. 铸造编号是否为字符,因此除了ascii字母外,它将失败.
  5. 只容忍字母a到z.无法处理空格,数字,符号或unicode.
  6. 代码违反了DRY(不要重复自己)原则,重复计算的次数超过了它.

伪代码:

  1. 循环遍历字符串中的每个字符.
  2. 添加到字符的移位,如果它从字母表的末尾落下,则从字母表中的字母数减去移位(26)
  3. 如果移位不会使角色从字母表的末尾掉落,则将移位添加到角色.
  4. 将字符附加到新字符串上.返回字符串.

功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

如何调用它:

System.out.println(cipher("abc", 3));  //prints def
System.out.println(cipher("xyz", 3));  //prints abc
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但应该使用StringBuilder而不是附加到String.请参阅:http://stackoverflow.com/questions/4645020/when-to-use-stringbuilder-in-java (2认同)

nan*_*oft 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();
    }
}
Run Code Online (Sandbox Code Playgroud)


azz*_*azz 1

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

Achar是16位,anint是32位。

char shift = 3;
// ...
eMessage[i] = (message[i] + shift) % (char)letters.length;
Run Code Online (Sandbox Code Playgroud)

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

char[] message = {'o', 'n', 'c', 'e', 'u', 'p', 'o', 'n', 'a', 't', 'i', 'm', 'e'}; 
Run Code Online (Sandbox Code Playgroud)

到:

char[] message = "onceuponatime".toCharArray();
Run Code Online (Sandbox Code Playgroud)