java - 凯撒密码在 Java 中被错误解码

标签 java java-8 decoding caesar-cipher decoder

我已经在Java 8中实现了凯撒密码算法。

问题

Heute ist Freitag.

使用 22 作为 key 生成此编码文本:

^{

{6

6{

w}D

再次解码得到这个输出:

Heu

e is

Frei

ag.

代码和描述

应该注意的是,我的算法不关心像“\n”这样的字符,这意味着某些字符可能会被转换为转义序列或空格等。 这也完全是我想要发生的事情,但认为它不起作用。

    public String encode(String txt, int key) {
    if(key <= 0)
        return txt;

    String result = "";
    for (int i = 0; i < txt.length(); i++) {
        int x = (txt.charAt(i) + key) % 128;
        result += (char) x;
    }
    System.out.println(result);
    return result;
    }
    public String decipherM(String txt, int key) {
    if(key <= 0)
        return txt;

    String result = "";
    for (int i = 0; i < txt.length(); i++) {
        int x = (txt.charAt(i) - key) % 128;
        if(x < 0)
            x += 128;

        result += (char) x;
    }
    System.out.println(result);
    return result;
}

问题

我真的很想知道为什么它不适用于转义序列或其他非字母字符。

最佳答案

控制字符具有定义的含义,文本处理工具可能会保留该含义,甚至删除那些没有有效含义的控制字符,而不是保留确切的字节表示形式。

请注意,当您超出 ASCII 范围时,普通字符甚至可能会发生这种情况,例如由于您使用的是德语示例文本,因此您必须注意两个 Unicode 代码点序列 \u00E4\u0061\u0308 在语义上是等效的,两者都引用字符 ä 并且您不能依赖文本处理工具来保留这两种形式。

毕竟,像Base 64这样的编码是有原因的。已被发明用于通过文本处理工具无损传输字节序列。

对于像您这样简单的编码,最好只是禁止源字符串中的控制字符并仅在 ASCII 非控制字符范围内循环:

public String encodeRotation(String txt, int distance) {
    int first = ' ', last = 128, range = last - first;
    while(distance<0) distance+=range;
    if(distance == 0) return txt;
    char[] buffer = txt.toCharArray();
    for (int i = 0; i < txt.length(); i++) {
        char c = buffer[i];
        if(c<first || c>=last)
            throw new IllegalArgumentException("unsupported character "+c);
        buffer[i] = (char) ((c - first + distance) % range + first);
    }
    return String.valueOf(buffer);
}

public String decodeRotation(String txt, int key) {
    return encodeRotation(txt, -key);
}
System.out.println(encodeRotation("Heute ist Freitag.", 22));
^{+*{6)*6\({*w}D
System.out.println(decodeRotation("^{+*{6)*6\\({*w}D", 22));
Heute ist Freitag.

关于java - 凯撒密码在 Java 中被错误解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46234086/

相关文章:

java - 在当前 Portlet 的 JSP 中定义另一个 Portlet Controller 的 ResourceUrl

java - 滥用 Optional#map 考虑缺少 Optional#peek 方法

shell - 如何使用unix命令对base64和base64URL中的数据进行编码和解码?

Android解码并保存从 Intent 返回的音频流

c++ - 将 mJPEG 解码为 libx264 可用的格式

java - 将日期和整数写入现有的 .pdf

Java-KeyListener : How to fire Events?

java - 磁盘上的 .class 文件是否必须遵循与其在 Java 中的限定名称相同的目录结构才能运行它?

Java 8 消费者和副作用

Java 8 流多线程