java - 带空格的凯撒密码解密方法
问题描述
我正在研究一个凯撒密码程序,作为我在 java I 中的最终项目。我有一种处理小写和大写字符的加密方法。但是,我在尝试调整算法以使移位因子在相反方向上工作以解密已经通过程序运行的文本时碰壁了。
另一个问题是我不能让程序使用空格,要么忽略它们,要么也加密它们。到目前为止,它只加密了第一个单词而忽略了其余的单词。到目前为止,这是我的加密方法,消息从 main() 作为参数传递。
//Caesar Cipher
public class EncryptionClass1 {
protected static String encryptedMessageString;
public static String setEncryptedMessage(String message) {
StringBuffer encryptedMessageBuffer = new StringBuffer();
char newCharacter;
int shiftFactor = 1;
int i;
//for length of secret message
for (i = 0; i<message.length(); i++) {
//uppercase encoder
if (Character.isUpperCase(message.charAt(i))) {
newCharacter = (char)(((int)message.charAt(i) -
shiftFactor - 65) % 26 + 65);
encryptedMessageBuffer.append(newCharacter);
}//if close
//lowercase encoder
else {
newCharacter = (char)(((int)message.charAt(i) -
shiftFactor - 97) % 26 + 97);
encryptedMessageBuffer.append(newCharacter);
}//else close
}//for close
//convert StringBuffer to string
encryptedMessageString = encryptedMessageBuffer.toString();
return encryptedMessageString;
}//setEncryptedMessage close
}//EncryptionClass1 close
对于解密,我认为我只需要针对加密方法调整一些操作,但我无法确定是什么。
至于空格,输入和输出示例应如下所示:
Input: “my secret message”
Output: rp dbxbbf rbddtfb
解决方案
要向相反方向移动,请进一步向当前方向移动。在 360° 表盘上可视化 26 个字母。如果加密是将表盘向右旋转 5 个字母,您通常会认为解密是将表盘向左旋转 5 个字母。但您也可以将表盘向右旋转 21 (26 - 5) 个字母。因此,如果加密正在上移shiftFactor
,那么解密也在上移26 - shiftFactor
。通过仅升档,% 26
操作将正确地环绕换档。
由于加密消息的长度始终与原始消息完全相同,并且一次只替换一个字母,因此如果您只处理char[]
原始消息中的一个,代码会更简单。如果你这样做,那么只需跳过数组中不是 ASCII 字母的字符。
不要使用幻数 65 和 97 ,而是使用它们的char
值来使代码更具可读性。
以上所有意味着您的代码可以这样编写:
private static final int SHIFT_FACTOR = 5;
public static String encryptMessage(String message) {
return applyShift(message, SHIFT_FACTOR);
}
public static String decryptMessage(String message) {
return applyShift(message, 26 - SHIFT_FACTOR);
}
private static String applyShift(String message, int shiftFactor) {
char[] chars = message.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c >= 'A' && c <= 'Z')
chars[i] = (char) ((c - 'A' + shiftFactor) % 26 + 'A');
else if (c >= 'a' && c <= 'z')
chars[i] = (char) ((c - 'a' + shiftFactor) % 26 + 'a');
}
return new String(chars);
}
测试
public static void main(String[] args) {
test("my secret message");
test("Hello World!");
}
private static void test(String message) {
String encrypted = encryptMessage(message);
System.out.println("Input : " + message);
System.out.println("Encrypted: " + encrypted);
System.out.println("Decrypted: " + decryptMessage(encrypted));
System.out.println();
}
输出
Input : my secret message
Encrypted: rd xjhwjy rjxxflj
Decrypted: my secret message
Input : Hello World!
Encrypted: Mjqqt Btwqi!
Decrypted: Hello World!
推荐阅读
- mongodb - how to use $match in $cond else section in mongodb
- dictionary - json解组后去映射结构类型转换
- swift - 如何获得 NSToolbar 高度?
- powerbuilder - 将新数据库列添加到 Powerbuilder DataWindow 后出现问题
- arrays - 如果单词以其中一个后缀结尾,则标记 1
- asp.net-core - 是否有针对 ASP.NET Core 的不同引导类的指南?
- xamarin.forms - Xamarin 中的砌体列表样式
- apache-spark - Spark CSV:解析由 Ascii æ (Hex E6) 分隔的文件
- python - 即使我下载了较新版本的python,我似乎也没有 pip
- c# - 使用 Stack 机器用 Brouncer 公式逼近 PI