Last active
June 5, 2023 15:44
-
-
Save sgtcortez/b51df067e864c2003b8243491bff21cb to your computer and use it in GitHub Desktop.
Serialize and Deserialize a number in C/C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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