使用数组java

时间:2017-02-24 17:20:44

标签: java encryption caesar-cipher vigenere

我需要先使用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;
 }
}

2 个答案:

答案 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()]