我在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;
}
我真的很想知道为什么它不能使用转义序列或其他非字母字符。
答案 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.