2012-05-15 68 views
3

我有一个无符号的字符数组,其尺寸是6字节数组的内容是一个整数(因为UNIX时间的秒4096 *号)。我知道字节数组是big-endian。如何将48位字节数组转换为C中的64位整数?

有没有在C库函数,我可以使用该字节数组转换成int_64还是我不得不手动做呢?

谢谢!

PS:万一你需要更多的信息,是的,我试图解析Unix时间戳。 Here是我处理的时间戳的格式规范。

+0

您必须手动这是很容易做到这一点。既然你是用字节顺序涉足,我建议你阅读[这](http://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html)罗布·派克的博客文章了。文章中包含了对你有所帮助的代码,只是不要直视它,阅读它。 –

+0

没有标准的C函数来做到这一点。不过,有可能是由使用此格式的任何库提供的函数。 –

回答

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

你有没有试过这样:

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; 

或者你可以用手,这将避免一些建筑的具体问题做。

我建议使用正常整数运算(总和和移位),而不是试图模仿存储器块排序,其不大于在兼容性的术语上述方案更好。

+1

仅当字节序与本地字节序匹配时才有效。 –

+0

是的。预处理器条件可能有助于选择正确的方式(如果性能很关键)。 –

+1

Nooooo no no no。请参阅弗朗西斯科·索托的答案中的博客文章,了解为什么在这些情况下应避免预处理器条件。 – dreamlax

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

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 
相关问题