我需要先使用Vigenere cypher加密然后解密消息。这是它应该如何工作
example message: "c a t s _ d o g s"
keyword "rats": r a t s r a t s r
order of the letter in the message (start at a=0):2 0 19 18 () 3 14 6 18
order of the letter in the keyword: 17 0 19 18 17 0 19 18 17
sum of the two orders: 19 0 38 36 17 3 39 24 35
new letter for the message* t a m k d h y j
encrypted message = "tamk uoyk"
*注意:如果总和> 26,那么我们从总和中减去26(得到一个循环字母表(例如:z + b = 25 + 1 = 26; 26-26 = 0 - > a)
我已经编写了获取关键字数值的方法,还有两个“添加”或“减去”单个字母的方法和两个执行凯撒编码/解码的方法(只需将整个消息移动一个int)在字母表的右边,或在左边解密)。
我真正需要帮助的部分是如何创建一个for循环,它将重复关键字适当的次数(与消息具有相同的长度)并继续到obtainKeys方法来获取数值重复键的值。
我希望我的解释有意义......
感谢您的帮助!
这是我的整个计划;我正在努力的部分是在最后(Q2f)
import java.util.Arrays;
public class Cypher{
public static void main(String[] args){
System.out.println(charRightShift('z',3));
System.out.println(charLeftShift('z',3));
String test = caesarEncode("cats and dogs",5);
System.out.println(test);
System.out.println(caesarDecode(test,5));
obtainKeys("abcxyz");
System.out.println(vigenereEncode("elephants", "rats"));
}
//Q2a-b
//Generalized method for char shifts
public static char charShift (char c, int n){
//value of n should be between 0 and 25
if(Math.abs(n)<0 || 25<Math.abs(n)){
//returning the ascii value of '0' which is nul & adding error message
int zero = 0;
c = (char)zero;
throw new IllegalArgumentException("n has to be 0<=|n|<=25");
}
//character c should be a lower case latin letter
//if not, we simply return c, the original character, skipping this else if
else if (c>='a' && c<='z'){
c = (char) (c+n);
if (c>'z'){
c = (char) (c-26);
}
else if(c<'a'){
c = (char) (c+26);
}
}
return c;
}
//method that shifts the value of the character to the right
public static char charRightShift(char c, int n){
c = charShift(c,n);
return c;
}
//method that shifts the value of the character to the left
public static char charLeftShift(char c, int n){
n = -n;
c= charShift(c,n);
return c;
}
//Q2c
//method that shifts the message to the right by int 'key' characters
public static String caesarEncode(String message, int key){
//transform string into char array
char[] messageEncrypt = message.toCharArray();
//for each char, we shift it by 'key' ints, using charRightShift method
for (int i=0; i<messageEncrypt.length; i++){
char c = messageEncrypt[i];
c = charRightShift(c,key);
messageEncrypt[i] = c;
}
return new String(messageEncrypt);
}
//Q2d
//method that shifts the message to the left by int 'key' characters
public static String caesarDecode(String message, int key){
//transform string into char array
char[] messageDecrypt = message.toCharArray();
//for each char, we shift it by 'key' ints using charLeftShift
for (int i=0; i<messageDecrypt.length; i++){
char c = messageDecrypt[i];
c = charLeftShift(c,key);
messageDecrypt[i] = c;
}
return new String(messageDecrypt);
}
//Q2e
//method to obtain the int array storing the numerical value of the String
public static int[] obtainKeys (String s){
//creating int array where we're going to store the numerical value of the String
int [] keys = new int[s.length()];
int j;
//for each ascii value of the char in string s, we substract 97 to get the lower case english alphabet character corresponding to it
for (int i=0; i<s.length(); i++){
char c = s.charAt(i);
j = c-97;
//now store every int in the int array
keys [i] = j;
}
String keysString = Arrays.toString(keys);
return keys;
}
//Q2f
public static String vigenereEncode(String message, String keyword){
//for loop check if there are any 'illegal' characters in the keyword
char[] kword = keyword.toCharArray();
for (int i=0; i<kword.length; i++){
char c = kword[i];
if(c<'a' || c>'z'){
throw new IllegalArgumentException("The keyword must only contain characters from the lower case English alphabet.");
}
}
int[] numMessage = obtainKeys(message);
int[] numKeyword = obtainKeys(keyword);
for(int i=0; i<message.length(); i++){
for(int j=0; j<keyword.length();i++){
//NOT SURE IF I NEED A NESTED LOOP HERE
//WHAT TO DO HERE?
}
}
return messageVigenere;
}
}
答案 0 :(得分:1)
您可以使用mod操作%
来完成此操作。
char[] messageArray = message.toCharArray();
char[] encryptedMessage = new char[messageArray.length];
int[] numKeyword = obtainKeys(keyword);
int keywordLength = numKeyword.length;
for(int i=0; i<message.length(); i++){
int shiftAmount = numKeyword[i % keywordLength];
char c = messageArray[i];
c = charRightShift(c,shiftAmount);
encryptedMessage[i] = c;
}
答案 1 :(得分:0)
不是重复关键字直到它是消息的长度,您可以使用模数逻辑找到所需的字母。对于邮件中的任何位置n
,关键字字母为keyword[n % keyword.length()]
。