How to map 6 bytes of raw data to long long type?

I'm trying to solve some problems for a contest, and I have a problem with it. I have to implement a function that has 3 arguments like this:

``````void foo(unsigned char* A, unsigned char* B, unsigned char* C);
``````

And what comes in, is 6 bytes of data. I have to convert these 6 bytes of data to integer data (maybe long long). The problem is, I don't know how to map the bytes in the right order.

I'm using an Arduino Uno board.

• What is the right order of the six bytes? And how are they contained in the `char` arrays from the functions parameters? Jul 10, 2018 at 7:06
• @chrisl 0x123412341234 to {0x12,0x34,0x12,0x34,0x12,0x34} Jul 10, 2018 at 9:05
• I'm not quite sure, what exactly you want to do. As I understand you get 3 char arrays with each 2 bytes in the correct order as parameters into your function, and then you want to declare a `long long` and fill the bytes from the arrays into this variable. Is this correct? Jul 10, 2018 at 10:10
• @chrisl nope. each of the parameters inputs 6 byte of data. and I want to convert it like what I said/ Jul 11, 2018 at 8:14

The trick is to use a `union` data type and get full control of the mapping. The issue of data representation and endian is now under your control:

``````uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
union {
uint64_t X;
struct {
uint8_t A[2];
uint8_t B[2];
uint8_t C[2];
uint8_t D[2];
};
} map;
#if defined(MSB_ORDER)
for (int i = 0, j = 1; i < 2; i++, j--) {
map.A[i] = 0;
map.B[i] = C[j];
map.C[i] = B[j];
map.D[i] = A[j];
}
#else
for (int i = 0; i < 2; i++) {
map.A[i] = A[i];
map.B[i] = B[i];
map.C[i] = C[i];
map.D[i] = 0;
}
#endif
return map.X;
}

void setup()
{
Serial.begin(9600);
while (!Serial);
uint8_t a[] = { 0x12, 0x34 };
uint8_t b[] = { 0x56, 0x78 };
uint8_t c[] = { 0x9a, 0xbc };
uint64_t res = foo(a, b, c);
Serial.print((uint32_t) (res >> 32), HEX);
Serial.print((uint32_t) res, HEX);
}

void loop()
{
}
``````

Cheers!

``````uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
uint64_t aux = 0;
aux = A[0];
aux <<= 8;
aux |= A[1];
aux <<= 8;
aux |= B[0];
aux <<= 8;
aux |= B[1];
aux <<= 8;
aux |= C[0];
aux <<= 8;
aux |= C[1];
return aux;
}
``````

following sample code:

``````  uint8_t a[] = { 0x12, 0x34 };
uint8_t b[] = { 0x56, 0x78 };
uint8_t c[] = { 0x9a, 0xbc };

uint64_t result = foo(a, b, c);

std::cout << std::hex << result;
``````

returns `123456789abc`, try the code here, excluding the std::out part, the same code will run on arduino without any problem

When passing data to functions you do this...

``````foo(a,b,c);
``````

You then extract the variables or data passed to the function like..

``````void foo(unsigned char* A, unsigned char* B, unsigned char* C) {
A = whatever;
B = whatever;
C = whatever;
}
``````
• wow. I'm not that noob ;; I wanna map the raw 6 byte data to "long long" type variable. memcpy won't work as I want, cause of the endian rules.. Jul 10, 2018 at 9:44
• Well your function was written wrong. So is each VAR or CHAR 2 bytes then? Jul 10, 2018 at 10:10