nani92 nani92 - 1 year ago 62
Python Question

How to have the correct representation of words in C+python+UART?

In a serial communication, I need to send that ciphertext from python to UART which is able to read it by using C.

At first, In the python side use this technique:


In the C side, I put the received ciphertext in a buffer. I test If the first byte 24, the Start of the packet:

if (buffer_RX[0]=='\x24')
for (i=1;i<=17;i++) //sizeof(buffer_RX)==17
printf("%x \n",buffer_RX[i]);
else {
printf("It is not a packet!");

The result that I have is:





So I have two questions,
- The fist is why
is displayed by that way, I mean just one zero 0?
- The second is how could I have this same representation:

const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};

If I suppose that is concatenation between bytes, I mean that is maybe:

unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];

But I am not sure, I think that I have a syntax error.

This representation will help me to continue next steps. But I don't know how could I have it please.

Answer Source

If you want to create a 4 byte long data from your 1 byte chunks.

const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};

It is not enough to OR the bytes, you have to shift them into the right position.

What you are currently doing, (note that you are over indexing plaintext[1] this should be plaintext[0]):

unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];

has this result in the memory, assuming int is 32 bit, 4 byte long:

| 3. byte | 2. byte | 1. byte |                   0. byte                      |
|  0x00   |   0x00  |   0x00  |   buffer_RX[3] | buffer_RX[4] | buffer_RX[5]   |

so you have to shift the appropriate bytes to the right position with the left-shift operator first <<, and OR the bytes after that.

Here is an example:

#include <stdio.h>

int main()
    unsigned char buffer_RX[4];

    buffer_RX[0] = 0x70;
    buffer_RX[1] = 0xb4;
    buffer_RX[2] = 0xc5;
    buffer_RX[3] = 0x5a;

    unsigned int plaintext[1];

    plaintext[0] = (buffer_RX[0]<<24) | (buffer_RX[1]<<16) | (buffer_RX[2]<<8) | buffer_RX[3];

    printf("plaintext: %08x\n", plaintext[0]);

    return 0;

The output:

enter image description here

In memory:

|     3. byte     |     2. byte    |     1. byte    |     0. byte    |
|  buffer_RX[0]   |  buffer_RX[1]  |  buffer_RX[2]  |   buffer_RX[3] |

You can see that buffer_RX[0] has been shifted by 24 which is 3 byte so it skips the first three cell, jumps to the last one.

buffer_RX[1] by 16 which is 2 byte, so it skips to first two, buffer_RX[2] by 8 which is 1 byte, so it skips the first. And buffer_RX[3] was not shifted because it goes to the first place.

Regarding the 0x00, it is zero represented on 8 bits. If your print it, that will be simply 0. If you print 0x0000 it will be 0 as well. It just how printf prints 0 by default, it does not prints zeros unnecessarly. If you have 0x70 in a 32 bit variable then it is actually 0x00000070 but printf will print 0x70, because unnecessary zeros are chopped off, unless you tell otherwise. That is where %02x comes in. In the %02x the 02 tells printf that you want to display 2 bytes no matter what so it will print two zeros in case of 0x00

printf("%02x \n",buffer_RX[i]);

If you want to print the whole 32 bit (4 byte) of 0x00000070 the following line will do that:

printf("%08x \n",buffer_RX[i]);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download