Search code examples
cbinarybitwise-operatorsbitbit-shift

how to reverse the Bit operation in C


I have the following C program which will get the MSB, 2nd MSB, 3rd MSB and LSB for value now 1588800373). How do I reverse it? That is, If the program has time_0 = 94, time_1 = 179, time_2 = 43, time_3 = 117, how do I construct it back to now = 1588800373;

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

int main()
{
  time_t now = 1588800373; //time(NULL);
  uint8_t time_0 = now >> 24;
  uint8_t time_1 = (now >> 16) & 0xFF;
  uint8_t time_2 = (now >> 8) & 0xFF;
  uint8_t time_3 = now & 0xFF;

  printf("%lu, %u, %u, %u, %u\n", now, time_0, time_1, time_2, time_3);
  // 1588800373, 94, 179, 43, 117

  return 0;
}

Solution

  • Shift the bytes with at least 32-bit unsigned math and then |.

    uint32_t repacked = ((uint32_t)time_0 << 24) | ((uint32_t)time_1 << 16) | 
        ((uint32_t)time_2 << 8) | time_3;
    time_t now_again = (time_t) repacked;
    

    time_0 << 24 by itself converts time_0 into an int and then shifts. This has the potential to shift into the sign bit of an int and is undefined behavior. On small platforms with 16-int, is it also UB to shift 16 or more. Use a wide enough unsigned type.


    Original code is subject to the y2038 bug should time_t encode as a 32-bit signed int. Better to first take time_t into a uint32_t and then split/shift into 4 bytes.