Caesar Cipher在Java中错误地解码

时间:2017-09-15 07:30:30

标签: java java-8 decoding caesar-cipher decoder

我在Java 8中实现了Caesar Cipher算法。

问题

  

Heute ist Freitag。

使用22作为关键字导致此编码文本:

  

^ {

     

{6

     

6 {

     

瓦特} d

再解码这个让我得到这个输出:

  

HEU

     

     

弗雷

     

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

问题

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

1 个答案:

答案 0 :(得分:3)

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

请注意,当您超越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.