Кодирование декодирование байт
У меня есть встроенное устройство, которое посылает мне дату 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
3 ответа:
Вы очистили свой socket_buf?
Вы убедились, что ваш компьютер большой enddian?
Кроме того, я предлагаю вам использовать оператор or вместо плюса.
Это может сэкономить вам больше времени.mypkt.dateTime = (long) ( ( socket_buf[0] << 24) | (socket_buf[1] << 16) | socket_buf[2] << 8) | (socket_buf[3] << 0));
Код записиlittle endian - он посылает наименее значимый байт первым.
Ваш код чтения ожидает big endian - он берет нулевой байт и сдвигает его влево на 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)NB: 16711840 не является "текущим" значением даты-времени эпохи Unix, какую бы конечность вы ни использовали для его представления. У вас могут быть другие проблемы в другом месте.
Поскольку
socket_buf
объявлен беззнаковым символом,socket_buf[0] << 24
является ошибкой.
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
.