Home > Software engineering >  Matching characters from two 1D arrays into a 2D array
Matching characters from two 1D arrays into a 2D array

Time:11-25

Essentially, I've created a vigenere cipher. Vigenere Cipher matrix

It's a method used for coding messages. I've created the 2D array for the Vigenere cipher array. I receive a message in a form of a .txt file to be encoded. I then convert this into a regular '1D character array'. Essentially reading the text and putting every single character into a new array.

I then also get input from the user for the key, this key is then taken and repeated to match the length of the character array. So now I have a 'key array'.

How a Vingere Cipher works is that the key's first letter and the texts first letter is matched. So on the X-Axis is the 'message' and on the Y-Axis is the 'key'.

For example, if I do key: road

and message: cars

the encrypted message would be: torv,

I would get T, because I started with R on the Y-Axis and matched it to C on the X-axis.

This is how I setup my Vigenere Cipher. where 'alphabet' is this. I'm just having trouble 'matching' the characters of the two arrays (encryption key) and (message) to my Vigenere Cipher, then saving that input as an array inside a method to be used later on. Currently, I'm not too worried about capital letters and so on.

Vigenere cipher code:

public static char[][] arrayMatrix (){
    char[][] arrayTabula = new char[26][26];
    for (int i=0;i<26;i  ){
        int x = i;
        for (int j=0; j<26; j  ){
            arrayTabula[i][j] = alphabet[x];
            if (x == 25){
                x = 0;
            }
            else
            x  ;
        }
    }
    return arrayTabula;
}

I've thought about converting the letters in the alphabet to a number, then using numbers to match said 'numbers' with my Tabula. I just thought this would be too tedious to do and re-convert back into 'normal' text. I am just wondering if there's a direct method of just matching my wanted X-axis with my 'message' and Y-axis with my 'key' and then finding the cross-sectional point.

Is anyone able to help me out?

CodePudding user response:

As per your code output of arrayTabula would be "a b c d e f g h i j k l m n o p q r s t u v w x y z " for 26 times.I think you no need to create x variable anymore, use i I am not quite understand your example, could you please one example? ...

public static char[][] arrayMatrix() {
        char[][] arrayTabula = new char[26][26];
        char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
        for (int i = 0; i < 26; i  ) {
            for (int j = 0; j < 26; j  ) {
                arrayTabula[i][j] = alphabet[j];
                System.out.print(arrayTabula[i][j] " ");
            }
            System.out.println();
        }`enter code here`
        return arrayTabula;
    }

...

CodePudding user response:

Matrix representation can be thought as this: matrix[y][x]

So in Vigenere Cipher, as a y you're going to use key's index and as a x you're going to use message's index for each character.

tabula[(index of 'r')][(index of 'c')] // would equal to = t as you mentioned for cars and road

I see that message length and key length that's why should be equal, this is what we are going to use and iterate through.

Shortly my approach was something like this:

public static void encrypt(String message, String key) {
        int stringLength = message.length(); // they've common length
        char[][] arrayTabula = arrayMatrix(); // table that you've created
        String encryptedText = "";

        for (int i = 0; i < stringLength; i  ) {

            // 97 is ascii code of 'a'. 
            // We want to access first index when we have 'a';
            // means = (int) 'a' - 97 = 0;
            // Applying for both y part and x part.
            int keysIndex = key.charAt(i) - 97; 
            int messagesIndex = message.charAt(i) - 97;

            //then correspondent `y` and `x` value is my encrypted char add it to my str
            encryptedText  = arrayTabula[keysIndex][messagesIndex];
        }
        System.out.println(encryptedText);
    }

Or if you don't want to use, 97 or any other ascii code. I would suggest you to use your alphabet char[] to find the index of each character.

Might be like that:

 public static int findIndex(char ch) {
        for (int i = 0; i < alphabet.length; i  ) {
            if (alphabet[i] == ch) {
                return i;
            }
        }
        return -1; // for not existing chars
    }

then the updated code would be :

...
int keysIndex = findIndex(key.charAt(i));
int messagesIndex = findIndex(message.charAt(i));
...

CodePudding user response:

for lower case only if you want to do it without the array:

public static String transform(String message, String key){
String mLower = message.toLowerCase();
String kLower = key.toLowerCase();
String result = "";
for(int i = 0; i < message.length(); i  ){
  int mNum = mLower.charAt(i) - 'a';
  int kNum = kLower.charAt(i) - 'a';
  int transformed = (kNum   mNum) % 26;
  transformed  = 'a';
  char t = (char)transformed;
  result  = t;
}
return result;

}

since each row starts with its own character and loops the alphabet by adding the index of the letter of the key to that of the letter of the message add them them get the modular of 26 you should get the result that you want.

  • Related