Имя: Пароль:
1C
1С v8
Цикличный избыточный код 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) А, ну если бред бредом погоняет, то нормально... "Искусственный интеллект не в силах преодолеть тупость естественного"©