2012-05-15 69 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 
相關問題