Дата возврата из 32-битного шестнадцатеричного - PullRequest
0 голосов
/ 13 марта 2020

У меня есть двоичный файл, который содержит данные из регистратора данных.

У меня очень криптовое c руководство, которое помогает пользователю декодировать двоичный файл, оно приводит пример: дата «28/04/14 12:25:39» кодируется в 32 битах: 0x3938C667

Сначала я ввел эту шестнадцатеричную строку в преобразователь Hex в De c и преобразователь Hex в Ascii в надежде, что он расшифрует ее до чего-то близкого к дате. Шестнадцатеричная строка даже не имеет достаточно цифр, чтобы равняться количеству цифр даты?

Дополнительная информация:

Вот некоторый код также в руководстве, не дает мне много информации ...

Дата / время хранятся в 4 байтах, и структура:

typedef union
{
     unsigned long val;
     struct
     {
          unsigned char seconds :6; // 00 - 59
          unsigned char minutes :6; // 00 - 59
          unsigned char hours :5; // 00 - 23
          unsigned char days :5; // 01 - 31
          unsigned char months :4; // 01 - 12
          unsigned char years :6; // 00 - 63
     };
}compact_date_t;

Ответы [ 3 ]

4 голосов
/ 13 марта 2020

Битовое поле дает вам почти все это.
Шесть младших битов за секунды. Давайте возьмем 6 младших битов - это будет

0x3938C667 & 0x3F = 0x27 = 39

** 0x3F - это 0000111111 в двоичном представлении - маскируя все, кроме младших 6 бит.

Следующие минуты - следующие 6 битов:

(0x3938C667 >> 6) & 0x3F = 0x19 = 25

... Остальное вы можете отработать самостоятельно

2 голосов
/ 13 марта 2020

Код в руководстве дает вам именно ту информацию, которая вам нужна. Это говорит о том, что первые 6 бит используются для «секунд», вторые 6 бит для «минут» и т. Д. c. Он сообщает вам точный формат даты в двоичном формате.

Если вы сложите все биты, вы получите 32 бита, что составляет 4 байта.

Важно знать, что это "справа налево". Другими словами, младшие 6 бит - это «секунды», а младшие 6 бит - «годы».

0 голосов
/ 13 марта 2020

Забудьте о битовых полях и используйте битовые операции для извлечения и кодирования даты. Вот вам go:

#include <time.h>
#include <stdint.h>

/**
tm_sec  int seconds after the minute    0-61*
tm_min  int minutes after the hour  0-59
tm_hour int hours since midnight    0-23
tm_mday int day of the month    1-31
tm_mon  int months since January    0-11
tm_year int years since 1900
*/

struct tm bits_to_date(uint_least32_t i) {
    return (struct tm){
        .tm_sec =  (i >> 0u              ) & ((1u << 6u) - 1u),
        .tm_min =  (i >> 6u              ) & ((1u << 6u) - 1u),
        .tm_hour = (i >> (6u+6u)         ) & ((1u << 5u) - 1u),
        .tm_mday = (i >> (6u+6u+5u)      ) & ((1u << 5u) - 1u),
        .tm_mon = ((i >> (6u+6u+5u+5u)   ) & ((1u << 4u) - 1u)) - 1,
        .tm_year = (i >> (6u+6u+5u+5u+4u)) & ((1u << 6u) - 1u),
    };
}

uint_least32_t date_to_bits(struct tm t) {
    return 
        (uint_least32_t)t.tm_sec |
        (uint_least32_t)t.tm_min << 6 |
        (uint_least32_t)t.tm_hour << (6u+6u) |
        (uint_least32_t)t.tm_mday << (6u+6u+5u) |
        ((uint_least32_t)t.tm_mon + 1u) << (6u+6u+5u+5u) |
        (uint_least32_t)t.tm_year << (6u+6u+5u+5u+4u);
}

#include <assert.h>
#include <string.h>
#include <stdio.h>
int main() {
    const struct tm d = {
            .tm_sec = 39,
            .tm_min = 25,
            .tm_hour = 12,
            .tm_mday = 28,
            .tm_mon = 03,
            .tm_year = 14,
    };
    uint_least32_t v = 0x3938C667;
    fprintf(stderr, "%#lX\n", date_to_bits(d));
    struct tm r = bits_to_date(v);
    fprintf(stderr, "%02d/%02d/%02d %02d:%02d:%02d\n",
        r.tm_mday, r.tm_mon+1, r.tm_year,
        r.tm_hour, r.tm_min, r.tm_sec
    );
    assert(date_to_bits(d) == 0x3938C667);
    assert(memcmp(&r, &d, sizeof(struct tm)) == 0);
}

Пророги выводят:

0x3938C667
28/04/14 12:25:39
...