Контрольная сумма (checksum)
Байт, пришедший по проводу или прочитанный из флеш-памяти, мог исказиться. Чтобы это заметить, передатчик вычисляет по данным короткое число и отправляет его вместе с ними, а приёмник считает его заново и сравнивает. Это число и называют контрольной суммой.
Обновлено Редакция GAW
Контрольная сумма (checksum) — короткое значение, которое вычисляют по блоку данных и передают или хранят вместе с ним, чтобы потом обнаружить искажение. Приёмник пересчитывает значение по полученным данным: не совпало — данные испорчены. В узком смысле так называют именно арифметические суммы байтов, в широком — любой проверочный код, включая CRC.
Простые суммы
Сумма по модулю 256. Все байты складываются, переносы отбрасываются, остаётся один байт. Его передают как есть или в виде дополнения, чтобы сумма всего пакета вместе с ним давала ноль.
LRC в Modbus ASCII. Спецификация Modbus по последовательной линии (разд. 2.5.2.2) задаёт её точно: сложить байты сообщения без переносов и взять дополнение до двух. Считают по двоичным байтам до кодирования в символы и без двоеточия в начале и CR LF в конце. Например, для байтов 01 03 00 00 00 0A сумма 0x0E, LRC = 0xF2.
Internet checksum (RFC 1071). Байты объединяют в 16-битные слова и складывают в обратном коде — перенос из старшего разряда добавляется к младшему. В поле записывают инверсию суммы; при проверке сумма по всему заголовку вместе с этим полем даёт все единицы. По RFC 1071 её используют стандартные протоколы IP, UDP и TCP.
Сумма или CRC
| Сумма байтов | CRC | |
|---|---|---|
| Вычисление | сложение | деление многочленов |
| Перестановка байтов | не замечает | как правило, замечает |
| Два ошибочных байта, компенсирующих друг друга | не замечает | как правило, замечает |
| Гарантия обнаружения | нет | только в пределах расстояния Хэмминга и длины пачки ошибок для данного полинома и длины данных |
| Стоимость | минимальная | таблица или сдвиги |
Modbus поэтому разделяет режимы: текстовый ASCII защищён LRC, двоичный RTU — CRC-16 (для CRC-16/MODBUS контрольное значение строки «123456789» — 0x4B37 по каталогу Грега Кука). Похожая идея на уровне одного символа — бит чётности.
Где встречается
В заголовках сетевых пакетов, в строках файлов прошивки Intel HEX, в кадрах датчиков вроде DHT22, в собственных протоколах поверх UART. Как выбрать проверку для своего кадра и проверить её в тестах — в статье о реализации протоколов; посчитать CRC с любыми параметрами можно в калькуляторе CRC.
Частые вопросы
Чем контрольная сумма отличается от CRC?
В широком смысле CRC — тоже контрольная сумма, но вычисляется она делением многочленов, а не сложением. Простая сумма байтов не замечает перестановку байтов и многие парные ошибки, когда один байт увеличился, а другой уменьшился на столько же. CRC такие ошибки, как правило, ловит, а гарантированно обнаруживает ошибки в пределах своего расстояния Хэмминга и длины пачки для выбранного полинома и длины данных. Modbus RTU использует CRC-16, а простую LRC оставил для текстового режима ASCII.
Как посчитать LRC для Modbus ASCII?
Сложить все байты сообщения — адрес, функцию и данные — по модулю 256, отбрасывая переносы, а затем взять дополнение до двух: LRC = (−сумма) mod 256. Считают по двоичным байтам до их кодирования в шестнадцатеричные символы, без начального двоеточия и без CR LF. Для байтов 01 03 00 00 00 0A сумма равна 0x0E, LRC — 0xF2.
Почему в Internet checksum используют сложение в обратном коде?
У него есть удобные свойства, перечисленные в RFC 1071: результат не зависит от порядка байтов в слове, поэтому машины с разной архитектурой считают одинаково, а при изменении одного поля сумму можно пересчитать без прохода по всему пакету. Проверка тоже проста: сумма вместе с полем контрольной суммы даёт все единицы.
Источники
- R. Braden, D. Borman, C. Partridge. RFC 1071: Computing the Internet Checksum, September 1988 — соседние байты объединяются в 16-битные слова и складываются в обратном коде (с циклическим переносом); для формирования поле суммы обнуляют, считают сумму и записывают её инверсию; при проверке сумма по тем же байтам вместе с полем суммы должна дать все единицы; сумму можно считать в любом порядке байтов
- Modbus Organization. MODBUS over Serial Line Specification and Implementation Guide V1.02, 2006 — разд. 2.5.2.2: в режиме ASCII поле LRC — один байт; LRC считают сложением байтов сообщения без переносов и дополнением результата до двух, по байтам до кодирования в ASCII, без начального двоеточия и завершающих CR LF; разд. 2.5.1.2: в режиме RTU используется CRC-16
- G. Cook. Catalogue of parametrised CRC algorithms with 16 bits, reveng.sourceforge.io, обновлено 11 декабря 2024 — CRC-16/MODBUS: poly 0x8005, init 0xFFFF, refin и refout true, xorout 0x0000, check 0x4B37
Нашли ошибку?
Смотрите также
- CRCЦиклический избыточный код для обнаружения ошибок
- Калькулятор CRCCRC-8, CRC-16, CRC-32, Modbus, блок CRC STM32, код на C
- Бит чётностиParity: контроль чётности символа UART, even и odd
- Реализация протокола обменаКадры по паузе, длине и разделителю, COBS, CRC-16, таймауты, разбор потока
- Просмотр Intel HEXЗаписи HEX и S19, контрольные суммы, карта памяти, дамп, HEX ↔ BIN
- КадрированиеСпособы отделить сообщения друг от друга в непрерывном потоке байтов