是否有人能够为此Columnar密码提供反向/解密算法?密钥长度可能会有所不同,但此处加密为4。
String input = "Hello World"
String output = "Hore llWdlo"
int key =4;
public static String encrypt(int key, String plainT) {
String outString= "";
for (int j = 0; j < key; j++) {
for (int i = j; i < plainT.length(); i += key) {
outString+= plainT.charAt(i);
}
}
return outString;
}
答案 0 :(得分:1)
Java字符串是不可变的,因此您无法对其数据进行操作。但是,如果您可以重写编码函数以使用字符数组:
public static String encrypt(int key, String plainT)
{
char[] res = new char[plainT.length()];
int k = 0;
for (int j = 0; j < key; j++) {
for (int i = j; i < plainT.length(); i += key) {
res[k++] = plainT.charAt(i);
}
}
return String.copyValueOf(res);
}
然后您可以轻松恢复该过程:
public static String decrypt(int key, String encT)
{
char[] res = new char[encT.length()];
int k = 0;
for (int j = 0; j < key; j++) {
for (int i = j; i < encT.length(); i += key) {
res[i] = encT.charAt(k++);
}
}
return String.copyValueOf(res);
}
此处使用辅助char
数组和附加索引k
实现连接。恢复过程与恢复索引相同。 (这意味着解密的数组不会按顺序填充,就像在加密时不按顺序读取原始字符串一样。)
(警告:我不熟悉Java,所以我希望更改char数组并将其转换为字符串就像我期望的那样工作,而且我还没有&#t; t告诉任何关于Java Strings的直截了当的废话。)
附录您也可以使用原始的连接代码作为基础,但它会更复杂一些。您的列式加密可以表示为:
H o r
e _ l
l W d
l o
水平读取加密字符串,垂直解密原始字符串。如果您的字符串为"Hello World!"
,并带有一个excamation标记,则您的字符串长度为12,并且您可以将原始代码与12 / 4 == 3
的还原密钥一起使用。
但实际上我们有一个变量键:第一行为3,最后一行为2。
public static String decrypt(int key, String str)
{
String out = "";
int skip = str.length() / key;
int rest = str.length() % key * (skip + 1);
for (int j = 0; j < skip; j++) {
int i = j;
while (i < str.length()) {
out += str.charAt(i);
i += skip;
if (i < rest) i++;
}
}
for (int i = skip; i < rest; i += skip + 1) {
out += str.charAt(i);
}
return out;
}
内部循环现在具有skip
或skip + 1
的键,具体取决于字符串的区域。最后一列(上面的草图)在一个单独的循环中处理,因为它看起来更整洁。