簡體   English   中英

如何將6字節數組轉換為數值?

[英]How can I cast a 6 byte array into a numerical value?

通常可以從char* buf檢索uint64_tuint32_t / uint16_t等,如下所示:

uint32_t val = *(uint32_t*) buf;

但現在假設bufchar [6] ,如何從中檢索數值?

*無符號大端(網絡字節順序)

一種便攜且符合標准的方式(與指針轉換或memcpy相反)將使其明確:

uint64_t val = 0;
for (int i = 0; i < 6; ++i)
    val |= (uint64_t)(unsigned char)buf[i] << (8*(6-i-1));

這假設是大端(網絡字節順序)。 unsigned char的額外強制轉換是一個hack,如果你的輸入數組已經是unsigned char*類型,你就不需要了。

使用uint64_t val = 0; memcpy(&val, buf, 6); uint64_t val = 0; memcpy(&val, buf, 6);

但要注意字節序問題(這個問題適用於小尾數val和buf)。

避免丑陋演員的另一種方法是使用聯盟:

union {
   uint64_t u64;
   uint8_t c[8];
} foo;

將字節按正確順序寫入foo.c[] ,然后訪問foo.u64 不是100%ISO C Kosher,但在大多數現代C實現上都是正確的。

我不會問你是如何得到一個大端的六字節緩沖區。

const int odd_buffer_size = 6;

char src[ odd_buffer_size ] = { … };
uint64_t dst = 0;

    // Copy the big-endian data into a big-endian long:
memcpy( ( (char*) & dst ) + 2, src, odd_buffer_size );
    // Read the data as a value (aliasing-safe) and convert endianness:
dst = ntohll( dst );

ntohll不是標准C,但可以在Windows中使用,有時在Linux上可用。 它的名稱似乎因平台而異(例如be64toh ),但有些設施始終可用。


順便說一句,技巧uint32_t val = *(uint32_t*) buf; 是不安全的,因為緩沖區可能(在這種特殊情況下,幾乎肯定是)不正確地對齊以訪問uint32_t值。

即使用奇數地址形成類型為uint32_t *的值也足以在C中崩潰。在重新解釋字節時,始終使用memcpyunion

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM