代入加密
Substitution encryption
我正在尝试在 java 中制作一个替代加密程序,但我在创建代码时遇到了问题,我想知道您是否有任何提示。我的想法是将字母表变成数字,然后将其与纯文本进行比较,然后制作一个新的字符串发回。
这是我的代码:
package ComputerSecurity;
public class Substitution {
String str = "abcdefghijklmnopqrstuvwxyz";
public String encrypt(int key, String plainText){
StringBuilder temp = new StringBuilder();
for(int i=0; i< plainText.length(); i++){
int position = plainText.charAt(i);
temp.append(str.charAt(plainText.indexOf(position)+key));
}
return temp.toString();
}
}
key=3
但是通过main方法plainText
发送进来的是"hello world".
我认为您尝试实施凯撒密码。
plainText.charAt(i)
returns 实际的当前字符,不是位置。您可以使用字符查找字母表中的位置:
char c = plainText.charAt(i)
int aPos = str.indexOf(c);
那你可以移动这个位置,得到加密的信件,但是你需要绕一圈。这通常通过模运算完成:
int encPos = aPos;
if (key >= 0) {
encPos = (aPos + key) % str.length();
} else {
// the key may be bigger than the alphabet length
encPos = (str.length() + ((key + aPos) % str.length())) % str.length();
}
char ec = str.indexOf(encPos);
对于 aPos
为 -1 的每个字符,您可以跳过加密。如果这样做,那么您还可以加密空格和其他非字母字符。
您对 return a "number string" 的想法的问题在于您不知道一个字符编号的结束位置和下一个字符编号的开始位置。所以,如果你想要那样,你将不得不添加分隔符,这会不必要地膨胀你的密文。
有3个问题:
- 您使用
str
。它将限制您可以使用的字母表。在你的情况下,大写的 H 和 W 以及两个单词之间的 space 将给出相同的输出,因为它们不在 str
. 中
- 此外,如果您尝试使用大于 3 的密钥加密 xyz,您最终会尝试在
str
. 中不存在的位置获取字符
- 最后,如果您不在我们的输出中使用分隔符,那么将很难区分 'ak' 和 'ka' 之类的情况,因为两者都将输出 '111',键为0.
我的建议是使用 char
的 int
值。你可以用 plainText.charAt(i)
.
得到它
对于 "abc" 它将 return 97、98 和 99,因为 a
的代码是 97。如果减去 96,a
将得到 1,[ 将得到 2 =19=]...
您只需将密钥添加到其中即可。
package ComputerSecurity;
public class Substitution {
public String encrypt(int key, String plainText){
StringBuilder temp = new StringBuilder();
for(int i=0; i< plainText.length(); i++){
int val = plainText.charAt(i) - 96;
temp.append((val+key) + ";");
}
return temp.toString();
}
encrypt(3, "Hello World")
将输出 -21,8,15,15,18,-61,26,18,21,15,7,
.
如果你想得到 11,8,15,15,18,-61,26,18,21,15,7,
把纯文本 toLowerCase()
.
我正在尝试在 java 中制作一个替代加密程序,但我在创建代码时遇到了问题,我想知道您是否有任何提示。我的想法是将字母表变成数字,然后将其与纯文本进行比较,然后制作一个新的字符串发回。
这是我的代码:
package ComputerSecurity;
public class Substitution {
String str = "abcdefghijklmnopqrstuvwxyz";
public String encrypt(int key, String plainText){
StringBuilder temp = new StringBuilder();
for(int i=0; i< plainText.length(); i++){
int position = plainText.charAt(i);
temp.append(str.charAt(plainText.indexOf(position)+key));
}
return temp.toString();
}
}
key=3
但是通过main方法plainText
发送进来的是"hello world".
我认为您尝试实施凯撒密码。
plainText.charAt(i)
returns 实际的当前字符,不是位置。您可以使用字符查找字母表中的位置:
char c = plainText.charAt(i)
int aPos = str.indexOf(c);
那你可以移动这个位置,得到加密的信件,但是你需要绕一圈。这通常通过模运算完成:
int encPos = aPos;
if (key >= 0) {
encPos = (aPos + key) % str.length();
} else {
// the key may be bigger than the alphabet length
encPos = (str.length() + ((key + aPos) % str.length())) % str.length();
}
char ec = str.indexOf(encPos);
对于 aPos
为 -1 的每个字符,您可以跳过加密。如果这样做,那么您还可以加密空格和其他非字母字符。
您对 return a "number string" 的想法的问题在于您不知道一个字符编号的结束位置和下一个字符编号的开始位置。所以,如果你想要那样,你将不得不添加分隔符,这会不必要地膨胀你的密文。
有3个问题:
- 您使用
str
。它将限制您可以使用的字母表。在你的情况下,大写的 H 和 W 以及两个单词之间的 space 将给出相同的输出,因为它们不在str
. 中
- 此外,如果您尝试使用大于 3 的密钥加密 xyz,您最终会尝试在
str
. 中不存在的位置获取字符
- 最后,如果您不在我们的输出中使用分隔符,那么将很难区分 'ak' 和 'ka' 之类的情况,因为两者都将输出 '111',键为0.
我的建议是使用 char
的 int
值。你可以用 plainText.charAt(i)
.
得到它
对于 "abc" 它将 return 97、98 和 99,因为 a
的代码是 97。如果减去 96,a
将得到 1,[ 将得到 2 =19=]...
您只需将密钥添加到其中即可。
package ComputerSecurity;
public class Substitution {
public String encrypt(int key, String plainText){
StringBuilder temp = new StringBuilder();
for(int i=0; i< plainText.length(); i++){
int val = plainText.charAt(i) - 96;
temp.append((val+key) + ";");
}
return temp.toString();
}
encrypt(3, "Hello World")
将输出 -21,8,15,15,18,-61,26,18,21,15,7,
.
如果你想得到 11,8,15,15,18,-61,26,18,21,15,7,
把纯文本 toLowerCase()
.