如何在C语言中将一个48位的字节数组转换成64位整数?

4
我有一个大小为6的无符号字符数组。字节数组的内容是一个整数(4096 * Unix时间秒数)。我知道字节数组是大端序的。
在C语言中是否有库函数可以将这个字节数组转换成int_64,还是必须手动转换?
谢谢!
PS:如果您需要更多信息,是的,我正在尝试解析Unix时间戳。 这里是我正在处理的时间戳格式规范。

没有标准的C函数可以做到这一点。但是可能有使用这种格式的库提供的函数。 - Oliver Charlesworth
你必须手动完成,这很容易。由于你正在涉足字节顺序问题,我建议你阅读Rob Pike的博客文章此处。该文章中包含对你有帮助的代码,但不要直接使用它,先仔细阅读。 - Francisco Soto
5个回答

8

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。这将在主机的本机字节顺序无关的情况下工作。

在C99中需要uint_least64_t。而C89没有保证64位整数 :D - Antti Haapala -- Слава Україні

0

你尝试过这个吗:

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;

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

我建议使用普通整数操作(求和和移位),而不是尝试模拟内存块排序,因为在兼容性方面与上述解决方案并没有什么区别。


True。如果性能很关键,预处理器条件可能有助于选择正确的方式。 - Samy Arous
1
不要使用预处理器条件。请参考Francisco Soto答案中链接的博客文章,了解为什么在这些情况下应避免使用预处理器条件。 - dreamlax
我今天学到的东西比原贴作者多,哈哈。 - Samy Arous

0

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

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

然后,您可以通过引用将该内存空间用作字节数组或uint64_t。

union time_u var_name;
var_name.data[i]
var_name.timestamp

1
这样做不行,因为问题说明了字节数组采用大端字节顺序。 - user694733

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 0111 0100 0110 假设val_ptr存储了num_in_48_bit的基地址。由于指针类型转换为uint8_t,增加val_ptr将给出下一个字节。循环并逐字节复制值。请注意,我也会处理网络到字节顺序。


1
你能解释一下吗? - Ahmet Sina Ustem
你能否编辑你的回答并加上这个解释?这样会更具信息量。 - Ahmet Sina Ustem

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接