Skip to content

Instantly share code, notes, and snippets.

@sgtcortez
Last active June 5, 2023 15:44
Show Gist options
  • Save sgtcortez/b51df067e864c2003b8243491bff21cb to your computer and use it in GitHub Desktop.
Save sgtcortez/b51df067e864c2003b8243491bff21cb to your computer and use it in GitHub Desktop.
Serialize and Deserialize a number in C/C++
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/**
* Function to serialize a unsigned 64 bit number to a byte array
* The serialization uses Little Endian to store the bytes in the byte array
* so, the least significant byte(LSB) is the first byte of array, and the
* most significant byte(MSB) is the last byte in the array
*/
void serialize(uint8_t *array, uint64_t number, uint8_t number_size);
/**
Function to deserialize a byte array to a unsigned 64 bits number
*/
uint64_t deserialize(uint8_t *array, uint8_t number_size);
// Number of bits the are in a single byte
#define BITS_IN_A_BYTE 8
int main(int argc, char* argv[])
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s number\n", argv[0]);
return 1;
}
uint64_t number64 = strtoull(argv[1], NULL, 10);
uint32_t number32 = number64 / 2;
uint16_t number16 = number32 / 2;
uint8_t number8 = number16 / 2;
uint8_t array64[sizeof(number64)];
uint8_t array32[sizeof(number32)];
uint8_t array16[sizeof(number16)];
uint8_t array8[sizeof(number8)];
serialize(array64, number64, sizeof(number64));
serialize(array32, number32, sizeof(number32));
serialize(array16, number16, sizeof(number16));
serialize(array8, number8, sizeof(number8));
uint64_t restored64 = deserialize(array64, sizeof(number64));
uint32_t restored32 = deserialize(array32, sizeof(number32));
uint16_t restored16 = deserialize(array16, sizeof(number16));
uint8_t restored8 = deserialize(array8, sizeof(number8));
printf("Number64: [%lu], Restored Number64: [%lu] Are they equals: %s\n", number64, restored64, (number64 == restored64) ? "yes" : "no");
printf("Number32: [%u], Restored Number32: [%u] Are they equals: %s\n", number32, restored32, (number32 == restored32) ? "yes" : "no");
printf("Number16: [%u], Restored Number16: [%u] Are they equals: %s\n", number16, restored16, (number16 == restored16) ? "yes" : "no");
printf("Number8: [%u], Restored Number8: [%u] Are they equals: %s\n", number8, restored8, (number8 == restored8) ? "yes" : "no");
return 0;
}
void serialize(uint8_t *array, uint64_t number, uint8_t number_size)
{
for (uint8_t index = 0; index < number_size; index++)
{
const int8_t shift_by = index * BITS_IN_A_BYTE;
// Since we use only the least significant 8 bits of the value(we do this by just using uint8_t)
// there is no need to do (number >> shift_by) & 0xFF to get the last 8 bits
const uint8_t result = number >> shift_by ;
array[index] = result;
}
}
uint64_t deserialize(uint8_t *array, uint8_t number_size)
{
uint64_t value = 0;
for (uint8_t index = 0; index < number_size; index++)
{
const int8_t shift_by = index * BITS_IN_A_BYTE;
// need to store it as uint64_t ...
// otherwise the next shift operation could overlflow if the shift_by is too big
uint64_t byte_value = array[index];
uint64_t result = byte_value << shift_by;
value |= result;
}
return value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment