I have an array of 64 characters, which I need to divide into two parts, the left part of 32 characters and the right part, also 32 characters.
char *IP_M; // 64 characters array
char L[32]; // left part
char R[32]; // right part
The IP_M array is filled in as follow:
char *start_inital_permutation(const char *input) {
char *output = malloc(64 * sizeof(char));
for (int i = 0; i < 8; i ) {
for (int j = 0; j < 8; j ) {
output[i * 8 j] = input[IP[i][j] - 1];
}
}
return output;
}
...
IP_M = start_inital_permutation(M);
where M is also a 64 characters string. With the following method I tried to fill the other two array (L, R) by spliting the IP_M.
void fill_LR() {
for (int i = 0; i < 32; i ) {
L[i] = IP_M[i];
R[i] = IP_M[i 32];
}
}
but when I run the following instructions:
printf("IP_M: %s\n", IP_M);
printf("L: %s\n", L);
printf("R: %s\n", R);
the output is:
IP_M: 1100110000000000110011001111111111110000101010101111000010101010
L: 1100110000000000110011001111111111110000101010101111000010101010
R: 11110000101010101111000010101010
I can't get out of this situation, can someone help me please?
*EDIT: also tried the memcpy()
method but it still not work!
Here is the Project if someone want to see it:
https://github.com/ionutbogdandonici/DES_C.git
CodePudding user response:
Strings in C are \0
terminated. So the print function will print the string until it reaches the \0
character.
Assign space for null:
char L[33]; // left part
char R[33]; // right part
Add null terminator:
void fill_LR() {
for (int i = 0; i < 32; i ) {
L[i] = IP_M[i];
R[i] = IP_M[i 32];
}
L[32] = 0;
R[32] = 0;
}
CodePudding user response:
output[i * 8 j] = input[IP[i][j] - 1];
is gibberish.- Strings in C are null terminated but you never allocate space for a null terminator anywhere, nor do you null terminate your strings.
- Don't use global variables.
I was able to salvage your program like this:
#include <stdio.h>
#include <stdlib.h>
char *start_inital_permutation(const char *input) {
size_t count=0;
char *output = malloc(64 * sizeof(char) 1);
for (int i = 0; i < 8; i ) {
for (int j = 0; j < 8; j ) {
output[i * 8 j] = input[count ];
}
}
output[64] = '\0';
return output;
}
int main()
{
const char input[] = "1100110000000000110011001111111111110000101010101111000010101010";
char *IP_M = start_inital_permutation(input);
char L[32 1]; // left part
char R[32 1]; // right part
for (int i = 0; i < 32; i ) {
L[i] = IP_M[i];
R[i] = IP_M[i 32];
}
L[32] = '\0';
R[32] = '\0';
printf("IP_M: %s\n", IP_M);
printf("L: %s\n", L);
printf("R: %s\n", R);
}
However, there's no apparent reason why you need to do the middle step with the 64 characters array. You could as well put that one in a union and save the copy (although then the individual left/right strings won't be null terminated). Example:
#include <stdio.h>
#include <stdlib.h>
typedef union
{
char data [64 1];
struct
{
char left[32];
char right[32];
char zero;
};
} ip_t;
ip_t *start_inital_permutation(const char *input) {
size_t count=0;
ip_t* obj = malloc(sizeof(ip_t));
for (int i = 0; i < 8; i ) {
for (int j = 0; j < 8; j ) {
obj->data[i * 8 j] = input[count ];
}
}
obj->data[64] = '\0';
return obj;
}
int main()
{
const char input[] = "1100110000000000110011001111111111110000101010101111000010101010";
ip_t *IP_M = start_inital_permutation(input);
printf("IP_M: %s\n", IP_M->data);
printf("L: %.32s\n", IP_M->left);
printf("R: %.32s\n", IP_M->right);
}
CodePudding user response:
Using printf
with "%s" assumes the value is a zero terminated string.
I.e. a pointer to a sequence of chars
, ending with a \0
char
.
In your case when printf
attempts to print L
it prints char
, and after the 32 char
s that belong to L
it continues. It happened to be that R
is following L
in memory, and so the content of R
is also dumped. If the next byte in memory following R
was not a 0
, you would see even more characters printed. This behavior is dependent on the [possibly atrbitarary] content of your memory.
How to handle the issue (2 ways):
You can either increase the size of L
and R
to 33, and assign the last char to \0
:
char L[33]; // left part
char R[33]; // right part
/* ... */
L[32] = '\0';
R[32] = '\0';
Or specify to printf
the length of the strings (32) like this:
/*----------vvv-------*/
printf("L: %.32s\n", L);
printf("R: %.32s\n", R);
In the later case keep in mind that L
and R
are not "regular" C strings, which are expected to be zero terminated (at least as far as it concerns common functions like strlen
, strcmp
etc.).