1

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

3

3 Answers 3

2

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; 
}
Sign up to request clarification or add additional context in comments.

6 Comments

Yeah! But why my L that have a size of 32 is filled up to 64 characters? The for runs assigns the value till i become 31
@BOGDANDONICI Where do you see it filled up with 64 characters? If there is no \0 byte after the 32 characters, printf will just continue in adjacent memory until it finda a \0 byte, no matter which variable is the memory belonging to.
So what should I do? Simply increment the size of the array by one and fill the position L[32] with ‘\0’?
@BOGDANDONICI Yes, see the edit of Gerhardh (thanks!)
That was the edit of another Gerhard ;)
|
0
  • 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);
}

Comments

0

Using printf with "%s" assumes the value is a zero terminated string (AKA NULL 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 chars 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):

1. 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';

2. 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.).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.