如何将48位字节数组转换为C中的64位整数?

时间:2012-05-15 23:58:51

标签: c endianness unix-timestamp type-conversion

我有一个大小为6的unsigned char数组。字节数组的内容是一个整数(自Unix时间以来的4096 *秒)。我知道字节数组是big-endian。

C中是否有一个库函数可用于将此字节数组转换为int_64,还是必须手动执行?

谢谢!

PS:以防您需要更多信息,是的,我正在尝试解析Unix时间戳。 Here是我处理的时间戳的格式规范。

5 个答案:

答案 0 :(得分:6)

C99实现可能会提供uint64_t(如果没有本机固定宽度整数正好是64位,则不必提供它),在这种情况下,您可以使用:

#include <stdint.h>

unsigned char data[6] = { /* bytes from somewhere */ };
uint64_t result = ((uint64_t)data[0] << 40) |
                  ((uint64_t)data[1] << 32) |
                  ((uint64_t)data[2] << 24) |
                  ((uint64_t)data[3] << 16) |
                  ((uint64_t)data[4] << 8)  |
                  ((uint64_t)data[5] << 0);

如果您的C99实施没有提供uint64_t,您仍然可以使用unsigned long long或(我认为)uint_least64_t。无论主机的本机字节顺序如何,这都将起作用。

答案 1 :(得分:1)

你试过这个:

unsigned char a [] = {0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned long long b = 0;
memcpy(&b,a,sizeof(a)*sizeof(char));
cout << hex << b << endl;

或者您可以手动完成,这将避免一些特定于架构的问题。

我建议使用正常的整数运算(求和和移位)而不是尝试模拟内存块排序,这在兼容性方面并不比上面的解决方案好。

答案 2 :(得分:1)

我认为最好的方法是使用联盟。

union time_u{
    uint8_t data[6];
    uint64_t timestamp;
}

然后,您可以通过引用

将该内存空间用作字节数组或uint64_t
union time_u var_name;
var_name.data[i]
var_name.timestamp

答案 3 :(得分:0)

您可以使用包选项

#pragma pack(1)

__attribute__((packed))

取决于编译器

typedef struct __uint48_t uint48_t;                                             
struct __attribute__((packed)) __uint48_t {                                     
    uint64_t _m:48;                                                             
};

__uint48_t data;

uint64_t result = data._m;

https://stackoverflow.com/a/13283703/995714

答案 4 :(得分:0)

这里是将其转换为64位的方法:

uint64_t
convert_48_to_64(uint8_t *val_ptr){
  uint64_t ret = 0;
  uint8_t *ret_ptr = (uint8_t *)&ret;

  for (int i = 0; i < 6; i++) {
      ret_ptr[5-i] = val_ptr[i];
  }
  return ret;
 }

 convert_48_to_64((uint8_t)&temp);  //temp is in 48 bit

例如:num_in_48_bit = 77340723707904;这个以48位二进制数表示的数字将是:0100 0110 0101 0111 0100 1010 0101 1101 0000 0000 0000 0000经过64位二进制数转换后将是:0000 0000 0000 0000 0000 0000 0000 0000 0101 1101 0100 1010 0101 0101 0111 0100 0110假设val_ptr存储num_in_48_bit的基地址。由于指针类型转换为uint8_t,因此递增val_ptr将为您提供下一个字节。循环遍历并逐字节复制值。注意,我也在照顾网络到字节的顺序。