Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15

Кодирование даты-времени, ищу ключ к протоколу обмена

24.04.2017, 00:48. Показов 3111. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет,

есть программа которая общается с сервером. Пытаюсь пропарсить протокол.
Есть последовательность байт, которая однозначно соответствует дате-времени.

8A B8 CC A1 F2 56 означает 20:00:00

C6 C6 C9 A1 F2 56 означает 19:59:36

Последний байт 56 точно соответствует 2017 году, так как в прошлом году здесь проходил байт 55.

Нужно выудить время. Уже голову сломал, помогите пожалуйста!!!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.04.2017, 00:48
Ответы с готовыми решениями:

Организация обмена по сети RS-485 с ПЛК CP317 по протоколу Modbus ASCII
есть собранная стойка, включающая в себя блок питания, CP317 и CP341. цель: реализовать обмен с оконечным устройством по интерфейсу RS485,...

Надо дописать!Ассемблер вывод системной даты,времени и даты ближайшего воскресенья
вот исходный код .Model Small .486p .Stack 100h .Data wNumOff DW 10 Dup(0) ;Смещение строки, где будет содержаться...

Вывод системной даты, времени и даты ближайшего воскресенья
вот исходный код выводит дату время .Model Small .486p .Stack 100h .Data wNumOff DW 10 Dup(0) ;Смещение строки, где...

12
Эксперт .NET
 Аватар для Rius
13151 / 7709 / 1679
Регистрация: 25.05.2015
Сообщений: 23,496
Записей в блоге: 14
24.04.2017, 06:48
Соберите хотя бы штук по 5 данных для одинаковых и разных часов, минут и секунд.
Например
20:00:00
20:00:10
20:00:15
20:00:20
20:00:59
10:00:00
11:00:00
12:00:00
13:00:00
14:00:00
15:01:00
15:02:00
15:03:00
15:04:00
15:05:00
0
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
25.04.2017, 01:09  [ТС]
с кодом 56:
08 A6 E5 F7 8F F4 56 надо получить 17:25:16, где A6 E5 F7 8F F4 56 по алгориму VarInt равно 1107161782
08 CE B0 F4 8F F4 56 надо получить 17:24:48, где CE B0 F4 8F F4 56 по алгориму VarInt равно 1107106558
08 E4 BC DE 8F F4 56 надо получить 17:21:48, где E4 BC DE 8F F4 56 по алгориму VarInt равно 1106747124
08 B2 DD C5 8F F4 56 надо получить 17:18:26, где B2 DD C5 8F F4 56 по алгориму VarInt равно 1106341554
08 FA EE BF 8F F4 56 надо получить 17:17:38, где FA EE BF 8F F4 56 по алгориму VarInt равно 1106245626
08 E2 EC BB 8F F4 56 надо получить 17:17:05, где E2 EC BB 8F F4 56 по алгориму VarInt равно 1106179826
08 E6 C7 AE 8F F4 56 надо получить 17:15:16, где E6 C7 AE 8F F4 56 по алгориму VarInt равно 1105979382

без кода 56:

08 BE CF F1 8F 0B 17:20:31
Декодируем BE CF F1 8F 0B по алгоритму VarInt превращаем в 2986108862, затем делим на 2000, делим на 86400 и получаем 17,280722581018518518518518518519 что есть 17 часов (целые) и 0.28072258 после запятой (или 16 минут 50 секунд), т.е. не совсем точно что хотелось. 4 минуты потерялись. А может это вообще подгонка.

08 F6 CA F1 8F 0B надо получить 17:15:39
Декодируем F6 CA F1 8F 0B по алгоритму VarInt превращаем в 2986108278, затем делим на 2000, делим на 86400 и получаем 17,280719201388888888888888888889 что есть 17 часов (целые) и 0.2807192 после запятой (или 16 минут 50 секунд), т.е. не совсем точно что хотелось. 4 минуты потерялись. А может это вообще подгонка.

08 E6 C7 F1 8F 0B надо получить 17:12:19
Декодируем E6 C7 F1 8F 0B по алгоритму VarInt превращаем в 2986107878, затем делим на 2000, делим на 86400 и получаем 17,280716886574074074074074074074 что есть 17 часов (целые) и 0.2807169 после запятой (или 16 минут 50 секунд), т.е. не совсем точно что хотелось. 4 минуты потерялись. А может это вообще подгонка.

Добавлено через 5 минут
в том смысле что иногда время приходит в двух форматах, с кодом 56 в конце, или без него.

Добавлено через 14 минут
08 C0 CB CF 91 F4 56 надо получить 17:54:44 где C0 CB CF 91 F4 56 равно 1110877942

08 86 E7 DE 91 F4 56 надо получить 17:56:48 где 86 E7 DE 91 F4 56 равно 1110946742

Добавлено через 6 минут
Там где нет кода 56, разница между двумя данными означает, что одна секунда представлена в виде двойки. Т.е, например 2986108862 минус 2986108278 соответствует разнице в секундах между 17:20:31 и 17:15:39 умноженной на два.
Но это относительно между ними, и когда знаешь во что пересчиать. А как узнать абсолютное значение? Как будто делить надо не на 86400, а на какое-то другое число, будто в сутках может быть чуть чуть больше или чуть чуть меньше секунд... бред.

Добавлено через 5 минут
08 DC C2 B4 92 F4 56 надо получить 18:08:30, где DC C2 B4 92 F4 56 равно 1112351740
0
Эксперт .NET
 Аватар для Rius
13151 / 7709 / 1679
Регистрация: 25.05.2015
Сообщений: 23,496
Записей в блоге: 14
25.04.2017, 06:58
Цитата Сообщение от gordom Посмотреть сообщение
08 A6 E5 F7 8F F4 56 надо получить 17:25:16
Это время возникновения события, расшифровываемое именно из этой посылки программой, которая понимает этот формат?
Или это ваше предположительное время, которое должно быть там?
Или вообще время фиксации сообщения?

Добавлено через 17 минут
Помимо времени, указывайте ещё и дату.
0
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
25.04.2017, 22:41  [ТС]
Все даты в моем втором посте - 24 апреля 2017.
Время указанное там - фактически то что должно быть после расшифровки, т.к. пока что у меня есть "дешифратор". Алгоритм дешифратора неясен, и есть необходимость от него отказаться, написав свой.

Добавлено через 5 минут
Вот где-то я рядом.
А именно:
берем код там где нет 56.
Наример, вот этот: 2986108862
Мы знаем уже, что одна секунда представлена в виде двойки.
Значит 2986108862 делим на 2, получаем время в секундах. С какого момента, или другими словами, какое время обозначено за ноль?
Считаем: 2986108862/2 = 1493054431
1493054431/ 86400 = 17280,722581018518518518518518519 Это ДНИ.
Поделим на 365 чтобы узнать сколько в этой цифре содержится лет: Ответ 47,344445427447995941146626078133
Вычтем из сегодняшней даты 47 лет и получим 1970 год. Начало Unix-эпохи?
ммм... Неужели это просто Unix время умноженное на два?
ГЫ идем на онлайн-конвертер, http://www.onlineconversion.com/unix_time.htm вводим 1493054431 и получаем:
Mon, 24 Apr 2017 17:20:31 GMT
Твою кочерыжку....

Остался вопрос по данным где есть 56. что это за зверь пока разбираюсь. Но тоже где-то также надо действовать.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
25.04.2017, 22:42
А что за секретная программа? Почему не посмотреть алгоритм в ней с помощью декомпилятора?
0
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
25.04.2017, 23:00  [ТС]
Идем дальше.
с кодом 56:
08 A6 E5 F7 8F F4 56 надо получить 17:25:16, где A6 E5 F7 8F F4 56 по алгориму VarInt равно 1107161782
08 E2 EC BB 8F F4 56 надо получить 17:17:05, где E2 EC BB 8F F4 56 по алгориму VarInt равно 1106179826

Откуда вычисляем что одна секунда это примерно 2000.
Тогда 1107161782 / 2000 = 553580,891 секунд... Начиная с какой даты?
553580,891 делим на 86400, получаем кол.дней = 6,4071862384259259259259259259259... Затык. что это еще??

Добавлено через 58 секунд
что за программа - торговый терминал на бирже. Уже свой написал по тем же данным, так как весь протокол разобрал по косточкам уже. Даты-время осталось. Пока что ставил везде локальное время, когда данные пришли. но пора и эту заглушку порешать.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
25.04.2017, 23:50
Лучший ответ Сообщение было отмечено gordom как решение

Решение

С 0x56 в конце все просто, там время в миллисекундах...

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        static ulong decode_unsigned_varint(byte[] data, out int decoded_bytes)
        {
            int i = 0;
            ulong decoded_value = 0;
            int shift_amount = 0;
 
            do
            {
                decoded_value |= (ulong)(data[i] & 0x7F) << shift_amount;
                shift_amount += 7;
            } while ((data[i++] & 0x80) != 0);
 
            decoded_bytes = i;
            return decoded_value;
        }
 
        // len == 6, val = 2986109432486
        ulong val = decode_unsigned_varint(new byte[] { 0xA6, 0xE5, 0xF7, 0x8F, 0xF4, 0x56 }, out int len);
        // 1493054716 = Monday, 24-Apr-17 17:25:16 UTC
        ulong time = val / 1000 / 2;
1
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
26.04.2017, 23:28  [ТС]
++++
Спасибо!!!!

Добавлено через 2 минуты
Что за алгоритм такой decode_unsigned_varint?

Добавлено через 53 секунды
нашел здесь http://stackoverflow.com/quest... ux-sockets

Получается в одном протоколе используются разные VarInt алгоритмы, один который я разгадал - один ваш. Хм...
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.04.2017, 01:37
Цитата Сообщение от gordom Посмотреть сообщение
Получается в одном протоколе используются разные VarInt алгоритмы, один который я разгадал - один ваш.
Нет, алгоритм один и тот же, varint... Код самый обычный и работает для обоих случаев...
0
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
27.04.2017, 10:53  [ТС]
По моему алгоритму A6 E5 F7 8F F4 56 равно 1107161782, по вашему - 2986109432486
значит они в чем-то разные, я теперь допускаю что где-то ошибся в переводе с языка с++ на дельфи.

Оригинал я браз здесь
https://techoverflow.net/2013/... ers-in-cc/

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Decodes an unsigned variable-length integer using the MSB algorithm.
 * @param value A variable-length encoded integer of arbitrary size.
 * @param inputSize How many bytes are 
 */
template<typename int_t = uint64_t>
int_t decodeVarint(uint8_t* input, size_t inputSize) {
    int_t ret = 0;
    for (size_t i = 0; i < inputSize; i++) {
        ret |= (input[i] & 127) << (7 * i);
        //If the next-byte flag is set
        if(!(input[i] & 128)) {
            break;
        }
    }
    return ret;
}

В дельфи перевел так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type size_t=UINT;
type int_t=UInt64;
type Auint8_t=array[0..7] of UInt8;
type Pout=^size_t;
 
function DecodeVarInt(input:Auint8_t; inputsize:size_t; outsize:Pout ):int_t;
var ret:int_t;
    k:size_t;
begin
    ret:=0;
    k:=0;
    while (k<inputsize) do
    begin
        ret:=ret or ((input[k] and 127) shl (7*k));
 
        if ((input[k] and 128)<1) then
            break;
        inc(k);
    end;
    outsize^:=k+1;
    result:=ret;
end;
Вроде без ошибок, а результат разный.

Добавлено через 29 минут
в смысле отличается от вашего.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
27.04.2017, 14:51
У меня что ваш, что найденный мной код работают корректно...

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        static ulong decodeVarint(byte[] input, out int consumedBytes)
        {
            consumedBytes = 0;
            ulong ret = 0;
            for (int i = 0; i < input.Length; i++)
            {
                ret |= (ulong)(input[i] & 0x7F) << (7 * i);
                //If the next-byte flag is set
                if (!((input[i] & 0x80) != 0))
                {
                    consumedBytes = i + 1;
                    break;
                }
            }
            return ret;
        }
C#
1
2
3
4
5
            ulong val = decodeVarint(new byte[] { 0xA6, 0xE5, 0xF7, 0x8F, 0xF4, 0x56 }, out int len); // 2986109432486
            ulong time = val / 1000 / 2; // 1493054716
 
            ulong val2 = decodeVarint(new byte[] { 0xE6, 0xC7, 0xF1, 0x8F, 0x0B }, out len); // 2986107878
            ulong time2 = val2 / 2; // 1493053939
0
0 / 0 / 1
Регистрация: 18.03.2015
Сообщений: 15
28.04.2017, 00:39  [ТС]
Долбаный дельфи. Оказывается побитовый сдвиг там по умолчанию 32-битный, если специально не указать.
Исправил код, все заработало:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function DecodeVarInt2(input:Auint8_t; inputsize:size_t; outsize:Pout ):int_t;
var ret,nxt:int64;
    k:size_t;
begin
    outsize^:=0;
    ret:=0;
    k:=0;
    for k:=0 to inputsize-1 do
    begin
        nxt:=[COLOR="Red"]int_t(input[k] and 127) shl int_t(7*k);[/COLOR]
        ret:=ret or nxt;
 
        if (input[k] and 128)=0 then
        begin
            outsize^:=k+1;
            break;
        end;
    end;
 
    result:=ret;
end;
Еще раз спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.04.2017, 00:39
Помогаю со студенческими работами здесь

Приложение для обмена денег на ключ
Приветствую господа форумчане! Привязка в железу программы, ограничение функционала в тестовом режиме и т.д. - все то, что провоцирует...

Программа должна работать до определенной даты у пользователя, независимо, что он выставит в настройках даты и времени
Добрый день, уважаемые! Уже сломал голову, но ничего не могу придумать. Дело вот в чем: есть программа (клиент обращений в поддержку),...

Почему при записи даты и времени из формы в бд, к времени прибавляется час?
Здравствуйте, при записи даты и времени из формы в бд, к времени прибавляется час, почему так происходит?

Поиск общего времени разговора на основе номера, времени и даты
Здравствуйте, Подскажите как можно подставить формулами время разговора&quot;Итог&quot; на основе телефона, времени, даты. Суть, надо в...

Ищу ключ mikroPascal PRO for AVR 3.5
Собственно сабж. Может ктонить поделится?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru