Search code examples
c++serializationdeserializationbyte-shifting

Deserialization of uint8 array to int64 fails but should work


Im going to send a int64 over tcp and need to serialize&deserialize it.

First i cast it to a uin64.

I byteshift it into an uint8 array.

Then i byteshift the array into a uint64

And finally cast it back to a int.

But it returns a different value than i put in... I have checked the hex values, but they are supposed to be correct...

Code:

#include <math.h>
#include <string.h>
#include <iostream>
#include <iomanip>

//SER & D-SER int64
std::array<uint8_t, 8> int64ToBytes(int64_t val)
{
   uint64_t v = (uint64_t)val;
   std::array<uint8_t, 8> bytes;
   bytes[0] = (v&0xFF00000000000000)>>56;
   bytes[1] = (v&0x00FF000000000000)>>48;
   bytes[2] = (v&0x0000FF0000000000)>>40;
   bytes[3] = (v&0x000000FF00000000)>>32;
   bytes[4] = (v&0x00000000FF000000)>>24;
   bytes[5] = (v&0x0000000000FF0000)>>16;
   bytes[6] = (v&0x000000000000FF00)>>8;
   bytes[7] = (v&0x00000000000000FF);
   return bytes;
}

int64_t bytesToInt64(uint8_t bytes[8])
{
   uint64_t v = 0;
   v |= bytes[0]; v <<= 8;
   v |= bytes[1]; v <<= 8;
   v |= bytes[3]; v <<= 8;
   v |= bytes[4]; v <<= 8;
   v |= bytes[5]; v <<= 8;
   v |= bytes[6]; v <<= 8;
   v |= bytes[7]; v <<= 8;
   v |= bytes[8];
   return (int64_t)v;
}


int main() {
   uint8_t bytes[8] = {0};

   int64_t val = 1234567890;

   //Print value to be received on the other side
   std::cout << std::dec << "INPUT:  " << val << std::endl;

   //Serialize
   memcpy(&bytes, int64ToBytes(val).data(), 8);

   //Deserialize
   int64_t val2 = bytesToInt64(bytes);

   //print deserialized int64
   std::cout << std::dec << "RESULT: " << val2 << std::endl;
}

Output:

INPUT:  1234567890
RESULT: 316049379840

Been trying to solve this for a day now, cant find the problem

Thanks.


Solution

  • Try using the uint64_t htobe64(uint64_t host_64bits) and uint64_t be64toh(uint64_t big_endian_64bits) functions to convert from host to big endian (network order) and from network order to host order respectively.

    You are shifting the entire value. Try something like:

    (bytes[0] << 56) | 
    (bytes[1] << 48) |
    ...  (bytes[7])
    

    There is no 9th byte (ie. byte[8]).