I have an assignment for the university to create a function that encrypts in C language. The full information is given below:
A scheme to encrypt letters is to fill a 8 x 8 array with the 26 capital letters of the English alphabet, the 26 small letters of the English, the ten digits ’0 ’ through ’9 ’, the space character ‘ ‘ and the ‘.’ character. Each character appears exactly once in the array. This array is called the encryption key.
To encrypt a letter pair, the rectangle formed by the two letters is used. Each letter of the original pair is replaced by the letter located on the same row and in the other corner of the rectangle. If both letters happen to be in the same row or column, the letters are swapped.
For example, according to the following key, the pair of letters AQ is encrypted as GV. Note the rectangle formed by the letters A and Q,
The letter A is replaced by G, which is the letter located on the same row and in the other corner of the rectangle.
The letter Q is replaced by V, which is the letter located on the same row and in the other corner of the rectangle.
Define and implement a function named encrypt that takes 3 arguments:
A 2-D array of characters as the encryption key,
The message to be encrypted (as a null-terminated array of characters)
An array of characters can be used to store the encrypted message.
The function encrypts the message according to the scheme described above and stores the encrypted message in the third parameter. If the original message contains an odd number of letters the last letter is unchanged.
Note: The terminating null should NOT be encrypted
For example, the word COMPUTER will be encrypted as VcrqGc
Note: for simplicity: The function named generate_key is already provided with this assignment. You do not have to create it. The function randomly fills an 8 x 8 array with the 26 capital letters of the English alphabet, the 26 small letters of the ten digits ’0 ’ through ’9 ’, the space ‘ ‘ and the dot ‘ .’.
I have created this function but it returns -1073741819 (0xC0000005).
void encrypt(char key[][8],char word[], char done[]){
int x,y,t,w,z,c=0;
while(word[c] != '\0'){
for(int j=0;j<8;j ){
for(int i=0;i<8;i ){
if(word[c]==key[i][j]){
x=i;
y=j;
}
if(word[c 1]==key[i][j]){
w=i;
z=j;
}
t=x;
x=w;
w=t;
done[c]=key[x][y];
done[c 1]=key[w][z];
}
printf("\n");
}
c=c 2;
printf("\n");
}
}
CodePudding user response:
Without seeing how you are calling this function, I built some supporting code to call this function. What I determined was that instead of testing the first and second character in a character pair in series like you have your code, you need to perform another loop test on the second character nested inside when the coordinates are found for the first character. Following is a bit of refactored code illustrating the nesting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char key[8][8] = { {'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', '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', '0', '1', '2', '3'},
{'4', '5', '6', '7', '8', '9', ' ', '.'},
};
void encrypt(char key[][8],char word[], char done[])
{
int x = 0, y = 0, t = 0, w = 0, z = 0, c=0;
while(word[c] != 0)
{
for(int j=0; j<8; j )
{
for(int i=0; i<8; i )
{
if(word[c]==key[i][j])
{
printf("i: %d, j: %d ", i, j); /* Nest the check of the second letter inside the first letter check */
for (int m = 0; m < 8; m )
for (int n = 0; n < 8; n )
if(word[c 1]==key[m][n])
{
printf("m: %d, n: %d \n", m, n);
w=j;
z=i;
x=n;
y=m;
}
}
done[c]=key[x][y];
done[c 1]=key[w][z];
}
}
c=c 2;
}
}
int main()
{
char test_word[32];
char encrypted_word[32];
for (int i = 0; i < 32; i )
{
encrypted_word[i] = 0;
}
strcpy(test_word, "Products");
encrypt(key, test_word, encrypted_word);
printf("Word: %s, Encrypted Word: %s\n", test_word, encrypted_word);
strcpy(test_word, encrypted_word);
for (int i = 0; i < 32; i )
{
encrypted_word[i] = 0;
}
encrypt(key, test_word, encrypted_word);
printf("Word: %s, Encrypted Word: %s\n", test_word, encrypted_word);
return 0;
}
Since theoretically, placing the encrypted word through this function should decrypt the word, I just called the function twice using a specific literal word to test. Following was the output on my terminal proving out this theory.
@Una:~/C_Programs/Console/Encryption/bin/Release$ ./Encryption
i: 1, j: 7 m: 5, n: 3
i: 5, j: 0 m: 3, n: 5
i: 5, j: 6 m: 3, n: 4
i: 5, j: 5 m: 5, n: 4
Word: Products, Encrypted Word: d5rFj1lt
i: 3, j: 5 m: 7, n: 1
i: 5, j: 3 m: 0, n: 5
i: 4, j: 3 m: 6, n: 5
i: 4, j: 5 m: 5, n: 5
Word: d5rFj1lt, Encrypted Word: Products
CodePudding user response:
Here is a (correct) alternate solution that takes advantage of the modulo operator.
Contiguous bytes in memory can be viewed as "8x8" or "64x1"... The approach below invokes strchr()
to find each input letter, then its index. The row & col can be derived from the byte's index. 'Pairing' the row of the 1st with the col of the 2nd involves some careful integer and modulo division.
The while()
conditional will only do pairs, and a bit of extra code handles the final char for string lengths that are odd.
void encrypt( char key[], char word[], char done[] ) {
for( int c = 0; word[c] != 0 && word[c 1] != 0 ; c = 2 ) {
int loc0 = strchr( key, word[ c 0 ] ) - key;
int loc1 = strchr( key, word[ c 1 ] ) - key;
done[ c 0 ] = key[ ( loc0 / 8 ) * 8 ( loc1 % 8 ) ];
done[ c 1 ] = key[ ( loc1 / 8 ) * 8 ( loc0 % 8 ) ];
}
if( word[c] != 0 ) { done[ c ] = word[ c ]; c = 1; }
done[ c ] = '\0';
printf( "'%s' ==> '%s'\n", word, done );
}
char key[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .";
void main( void ) {
char buf[2][32];
encrypt( key, "Products", buf[0] );
encrypt( key, buf[0], buf[1] );
}
This encryption corrects some mysterious 'transposition' so it does not match NoDakker's version. (But, this version of the output checks out manually using NoDakker's supplied 'matrix'.)
Output:
'Products' ==> 'LvtYsest'
'LvtYsest' ==> 'Products'