Converting 4 bytes in little endian order into an

2020-06-04 06:10发布

问题:

I have a string of 256*4 bytes of data. These 256* 4 bytes need to be converted into 256 unsigned integers. The order in which they come is little endian, i.e. the first four bytes in the string are the little endian representation of the first integer, the next 4 bytes are the little endian representation of the next integer, and so on.

What is the best way to parse through this data and merge these bytes into unsigned integers? I know I have to use bitshift operators but I don't know in what way.

回答1:

Hope this helps you

unsigned int arr[256];
char ch[256*4] = "your string";
for(int i = 0,k=0;i<256*4;i+=4,k++)
{
arr[k] = ch[i]|ch[i+1]<<8|ch[i+2]<<16|ch[i+3]<<24;
}


回答2:

Alternatively, we can use C/C++ casting to interpret a char buffer as an array of unsigned int. This can help get away with shifting and endianness dependency.

#include <stdio.h>
int main()
{
    char buf[256*4] = "abcd";
    unsigned int *p_int = ( unsigned int * )buf;
    unsigned short idx = 0;
    unsigned int val = 0;
    for( idx = 0; idx < 256; idx++ )
    {
        val = *p_int++;
        printf( "idx = %d, val = %d \n", idx, val );
    }
}

This would print out 256 values, the first one is idx = 0, val = 1684234849 (and all remaining numbers = 0).

As a side note, "abcd" converts to 1684234849 because it's run on X86 (Little Endian), in which "abcd" is 0x64636261 (with 'a' is 0x61, and 'd' is 0x64 - in Little Endian, the LSB is in the smallest address). So 0x64636261 = 1684234849.

Note also, if using C++, reinterpret_cast should be used in this case:

const char *p_buf = "abcd";
const unsigned int *p_int = reinterpret_cast< const unsigned int * >( p_buf );


回答3:

If your host system is little-endian, just read along 4 bytes, shift properly and copy them to int

char bytes[4] = "....";
int i = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);

If your host is big-endian, do the same and reverse the bytes in the int, or reverse it on-the-fly while copying with bit-shifting, i.e. just change the indexes of bytes[] from 0-3 to 3-0

But you shouldn't even do that just copy the whole char array to the int array if your PC is in little-endian

#define LEN 256
char bytes[LEN*4] = "blahblahblah";
unsigned int uint[LEN];
memcpy(uint, bytes, sizeof bytes);

That said, the best way is to avoid copying at all and use the same array for both types

union
{
    char bytes[LEN*4];
    unsigned int uint[LEN];
} myArrays;

// copy data to myArrays.bytes[], do something with those bytes if necessary
// after populating myArrays.bytes[], get the ints by myArrays.uint[i]