[英]Encoding decoding bytes
我有一個嵌入式設備,以這種格式發送UTC日期(日期是4個字節):
buffer.push_back((BYTE)(time_utc & 0x000000FF));
buffer.push_back((BYTE)((time_utc & 0x0000FF00) >> 8));
buffer.push_back((BYTE)((time_utc & 0x00FF0000) >> 16));
buffer.push_back((BYTE)((time_utc & 0xFF000000) >> 24));
在服務器上,我收到字節並將它們存儲在socket_buf
,從索引0-3開始並使用以下邏輯對其進行解碼
mypkt.dateTime = ( ( socket_buf[0] << 24) +
(socket_buf[1 ] << 16) + socket_buf[2] << 8) +
(socket_buf[3] << 0));
但我不確定是否正確解碼它,因為我得到的日期不正確。 任何人都可以建議我解碼它的正確方法嗎? 我使用Linux命令解碼日期(16711840是我通過解碼獲得的數字):
#date -d @16711840
編寫代碼是小端 - 它首先發送最低有效字節。
你的閱讀代碼期待大端 - 它采用第0個字節並將其向左移位24位。
請注意,在這兩種情況下,代碼都不依賴於本地機器的字節序 - 所寫的代碼與此無關,只是它們彼此不一致。
試試這個,相反:
mypkt.dateTime = ((socket_buf[0] << 0) +
(socket_buf[1] << 8) +
(socket_buf[2] << 16) +
((uint32_t)socket_buf[3] << 24));
強制轉換是必要的(但僅限於最后一次轉換),因為0x80 - 0xff
將轉換為有signed int
,並且未定義移位到符號位的位會發生什么(感謝@Lundin)
注意:16711840不是“當前”Unix紀元日期時間值,無論您使用哪個字節順序代表它。 你可能在其他地方有其他問題。
由於socket_buf
聲明為unsigned char,因此socket_buf[0] << 24
是一個bug。
socket_buf[0]
是unsigned char,將整數提升為int
。 在這個特定系統上是16位還是32位並不重要,因為程序無論如何都會崩潰。 在這兩種情況下,它最終都是一個有符號的變量。 您將左移一個帶符號的變量並將二進制變換為符號位。 然后你對此做了補充。
編寫解碼的正確方法是:
mypkt.dateTime = ( ((uint32_t)socket_buf[0] << 24) |
((uint32_t)socket_buf[1] << 16) |
((uint32_t)socket_buf[2] << 8) |
((uint32_t)socket_buf[3] << 0) );
此外,您似乎在編碼和解碼之間向后更改字節順序。 我不太清楚與endianess有什么關系,你的代碼只是在buffer
與sock_buf
之間使用不一致的順序。
你清除了socket_buf嗎?
你確定你的電腦是大端的嗎?
另外,我給你一個建議:使用或運算符而不是加號。
這可以為您節省更多時間。
mypkt.dateTime = (long) ( ( socket_buf[0] << 24) | (socket_buf[1] << 16) | socket_buf[2] << 8) | (socket_buf[3] << 0));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.