我有一个大小为 6 的无符号字符数组。字节数组的内容是一个整数(4096 * 自 Unix 时间以来的秒数)。我知道字节数组是大端的。
C 中是否有一个库函数可用于将此字节数组转换为 int_64 还是必须手动执行?
谢谢!
PS:以防万一您需要更多信息,是的,我正在尝试解析 Unix 时间戳。这是我处理的时间戳的格式规范。
我有一个大小为 6 的无符号字符数组。字节数组的内容是一个整数(4096 * 自 Unix 时间以来的秒数)。我知道字节数组是大端的。
C 中是否有一个库函数可用于将此字节数组转换为 int_64 还是必须手动执行?
谢谢!
PS:以防万一您需要更多信息,是的,我正在尝试解析 Unix 时间戳。这是我处理的时间戳的格式规范。
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
or (我认为) uint_least64_t
。无论主机的本机字节顺序如何,这都将起作用。
你试过这个:
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;
或者您可以手动完成,这将避免一些特定于架构的问题。
我建议使用正常的整数运算(求和和移位),而不是尝试模拟内存块排序,这在兼容性方面并不比上述解决方案好。
我认为最好的方法是使用工会。
union time_u{
uint8_t data[6];
uint64_t timestamp;
}
然后,您可以通过引用将该内存空间用作字节数组或 uint64_t
union time_u var_name;
var_name.data[i]
var_name.timestamp
这是一种将其转换为 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 将为您提供下一个字节。循环并逐字节复制值。请注意,我也在按字节顺序处理网络。
您可以使用打包选项
#pragma pack(1)
或者
__attribute__((packed))
取决于编译器
typedef struct __attribute__((packed))
{
uint64_t u48: 48;
} uint48_t;
uint48_t data;
memcpy(six_byte_array, &data, 6);
uint64_t result = data.u48;
看