![]() |
![]() |
|
Цикличный избыточный код CRC-16 Modbus | ☑ | ||
---|---|---|---|---|
0
Elf_80_lvl
05.09.25
✎
14:25
|
Есть задачка, посчитать CRC16 Modbus. Не думал что с этим возникнут проблемы, вроде как есть формула и есть условный сайт где можно проверить расчет. Но я никак не могу выйти на этот результат.
Тестовая строка "123456789" Мировой разум подсказывает решение и "любезно" предлагает даже тестовый ответ. ПодробностиНиже приведён пример функции на 1С (8.3), которая рассчитывает CRC-16 Modbus (полином 0xA001, начальное значение 0xFFFF): // Функция сдвига вправо, т.к. в 1С нет оператора >> Функция СдвигВправо(Число, КолВоБит) Возврат Цел(Число / (2 ^ КолВоБит)); КонецФункции // Функция расчёта CRC-16 Modbus Функция CRC16Modbus(Данные) // Данные — строка в ANSI (каждый символ — байт) CRC = 16#FFFF; Полином = 16#A001; Для i = 1 По СтрДлина(Данные) Цикл Байта = КодСимвола(Сред(Данные, i, 1)); CRC = CRC XOR Байта; Для j = 1 По 8 Цикл Если (CRC & 1) = 1 Тогда CRC = СдвигВправо(CRC, 1) XOR Полином; Иначе CRC = СдвигВправо(CRC, 1); КонецЕсли; КонецЦикла; КонецЦикла; Возврат CRC; КонецФункции --- ▎Пример вызова и вывода результата: Данные = "123456789"; // стандартный тестовый набор для CRC CRC = CRC16Modbus(Данные); Сообщить("CRC-16 Modbus: " + Формат(CRC, "X4")); // Выведет: CRC-16 Modbus: 4B37 Ну то что код совсем кривой это фиг с ним, какбудто можно допилить, НО меня смущает, что тестовый запрос возвращает ответ 4B37 При этом контрольный сайт, который даёт мне постановщик задачи https://www.lammertbies.nl/comm/info/crc-calculation Показывает для такой же строки ответ 0x4B37 Теперь я в замешательстве, есть какие то разные методы расчета CRC16 Modbus? Может быть у кого то есть рабочий пример такого рачета на 1С? |
|||
1
Elf_80_lvl
05.09.25
✎
10:17
|
Блин, написал херню. Ответ же одинаковый. Ладно попробую перевести говнокод мирового разума на православный 1с
|
|||
2
arsik
гуру
05.09.25
✎
10:34
|
Рассчитай 2 раза CRC-8 и потом сложи
Или 1 раз CRC-32 и раздели на 2 :) |
|||
3
Elf_80_lvl
05.09.25
✎
10:43
|
О да =)
|
|||
4
arsik
гуру
05.09.25
✎
10:59
|
Это старый код, в 1с давно уже завезли побитовые операции
Например ПобитовыйСдвигВправоГлобальный контекст (Global context) ПобитовыйСдвигВправо (BitwiseShiftRight) Синтаксис: ПобитовыйСдвигВправо(<Число>, <Смещение>) Параметры: <Число> (обязательный) Тип: Число. Число, для которого требуется выполнить сдвиг. Значение должно быть целым числом в диапазоне от 0 до 2^32-1. Если число не целое или не укладывается в данный диапазон - генерируется исключение. <Смещение> (обязательный) Тип: Число. Количество битов, на которое требуется выполнить сдвиг. Значение должно быть целым числом в диапазоне от 0 до 31. Если число не целое или не укладывается в данный диапазон, будет сгенерировано исключение. Возвращаемое значение: Тип: Число. Итоговое число после сдвига. Описание: Выполняет побитовый сдвиг двоичного представления числа на заданное количество битов вправо. Доступность: Тонкий клиент, веб-клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер, интеграция. Примечание: Освободившиеся разряды заполняются нулями. Пример: Функция ПолучитьНалоговуюСтавку(Свойства) МаскаНалоговаяСтавка = ЧислоИзДвоичнойСтроки ("0b00000000001111000000000000000000"); НалоговаяСтавка = ПобитовоеИ(Свойства, МаскаНалоговаяСтавка); Возврат ПобитовыйСдвигВправо(НалоговаяСтавка, 18); КонецФункции Использование в версии: Доступен, начиная с версии 8.3.11. |
|||
5
АгентБезопасной Нацио
05.09.25
✎
14:17
|
(0) Байта = КодСимвола(Сред(Данные, i, 1)); Это шозанах?
У "0" код не 0, а емнип, 48dec/30hex, у "A" - не 10dec, а 65dec/41hex |
|||
6
Garykom
гуру
05.09.25
✎
14:19
|
(5) Это бред от нейронки
|
|||
7
Djelf
05.09.25
✎
14:34
|
Что-то я не пойму, чем отличается "4B37" от "0x4B37", кроме как указанием шестнадцеричного кода "0x" спереди во втором случае...
(0) Потребуется - добавь, не потребуется - не добавляй. А... ну 2й пост не прочитал, сори. Ты и сам это уже понял. |
|||
8
Волшебник
05.09.25
✎
14:33
|
(7) в языках типа C или PHP это признак литерала в виде 16-ричного числа
|
|||
9
Djelf
05.09.25
✎
14:34
|
(8) А я что написал? Что-то наоборот?
|
|||
10
Волшебник
05.09.25
✎
14:39
|
(9) Вы написали, что Вы не понимаете. Я Вам объяснил
|
|||
11
Djelf
05.09.25
✎
22:12
|
(10) Это было написано для автора, я-то это понимаю уже лет 30 ;)
|
|||
12
АгентБезопасной Нацио
05.09.25
✎
15:25
|
(6) А, ну если бред бредом погоняет, то нормально... "Искусственный интеллект не в силах преодолеть тупость естественного"©
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |