2011-09-10 57 views
0

我需要能夠將數值發送到遠程套接字服務器,因此我需要將可能的數字編碼爲字節。如何將數值編碼爲字節

這些數字最多爲64位,即最多需要8個字節。第一個字節是類型,它始終是255以下的數字,因此適合1個字節。

例如,如果數字是8並且類型是32位無符號整數,那麼類型將是7,它將被複制到第一個(最左邊的)字節,然後接下來的4個字節將用實際數字(在這種情況下爲8)。

所以以字節爲單位:

byte1: 7 
byte2: 0 
byte3: 0 
byte4: 0 
byte5: 8 

我希望這是決策意識。

執行此編碼的代碼看起來是否合理?

int type = 7; 
uint32_t number = 8; 

unsigned char* msg7 = (unsigned char*)malloc(5); 
unsigned char* p = msg7; 

*p++ = type; 

for (int i = sizeof(uint32_t) - 1; i >= 0; --i) 
    *p++ = number & 0xFF << (i * 8); 
+0

[不要在C中輸入'malloc'的結果](http://stackoverflow.com/q/605845/995714) –

回答

3

你要明確投type避免警告:

*p++ = (unsigned char) type; 

你想要加入首先對最重要的字節進行編號,但是您的方向錯誤。迴路應該是:

for (int i = sizeof(uint32_t) - 1; i >= 0; --i) 
    *p++ = (unsigned char) ((number >> (i * 8)) & 0xFF); 

否則看起來不錯。

+0

您還修復了另一個您沒有提到的問題:他的代碼正在移動0xff掩碼,而不是「數字」,因此4個字節中的3個始終設置爲零。不過,它固定在你的手中。 – Dmitri

+0

正如在這種情況下,每當我不確定優先級時,我都認爲沒有其他人會確定其中的任何一個,並且我使用圓括號將其清除。 –

0

你的意思是?

for (int i = sizeof(uint32_t) - 1; i >= 0; --i) 
    *p++ = (number >> (i * 8)) & 0xFF; 

另一種選擇可能是做

// this would work on Big endian systems, e.g. sparc 
struct unsignedMsg { 
    unsigned char type; 
    uint32_t value; 
} 

unsignedMsg msg; 
msg.type = 7; 
msg.value = number; 
unsigned char *p = (unsigned char *) &msg; 

unsigned char* p = 
p[0] = 7; 
*((uint32_t *) &(p[1])) = number; 
+0

'value'的字節表示是否取決於平臺的字節順序? –

+0

@Tom,是的,我稍後添加了評論。只要平臺匹配,它不會是一個問題。 x86/x64系統通常是小端,這是要求的。 –

+1

OP在最後一個字節中有8個 - 是不是那個大端? –

0

你的代碼是合理的(雖然我會使用uint8_t,因爲你沒有使用字節爲「人物」,彼得當然是正確的WRT錯字),而不像像

uint32_t number = 8; 
uint8_t* p = (uint8_t *) &number; 
的常見方案

union { 
    uint32_t number; 
    uint8_t bytes[4]; 
} val; 
val.number = 8; 
// access val.bytes[0] .. val.bytes[3] 

即使是保證工作。第一種方法可能在調試版本中工作,但是越來越多的編譯器在優化時可能會破壞它,而第二種方法往往可以在任何地方實際工作,但被語言標準明確標記爲壞事™。

0

我會下降循環,使用「來電者分配」的界面,像

int convert_32 (unsigned char *target, size_t size, uint32_t val) 
{ 
if (size < 5) return -1; 

target[0] = 7; 
target[1] = (val >> 24) & 0xff; 
target[2] = (val >> 16) & 0xff; 
target[3] = (val >> 8) & 0xff; 
target[4] = (val) & 0xff; 

return 5; 
} 

這使得它更容易爲呼叫者多個片段連接成一個大的二進制包,並跟蹤中的使用/所需的緩衝區大小。

+0

關於調用者分配的好處。我會用這個想法。 –

相關問題