Re[8]: Протокол на основе UDP
От: fk0 Россия https://fk0.name
Дата: 03.03.10 08:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>>>то у меня получается в самом коротком случае 3 байта испорченных, иногда 4, обычно же оно не находит случаев короче чем 8 байт. Для CRC-8 это очень хороший результат. А твой пример умудряется находить даже последовательности с изменением одного последнего байта, что заведомо показывает на ошибочность твоего кода (собственно почему я и стал рыть).

fk0>> Исправил. Так ведь получается. Вот пример для 1000 запусков:
N>Ничего неожиданного. Естественно, можно подобрать такие данные, что на них с подобной стандартной заменой получится "немного" не то, но с той же суммой.
N>Но для таких ситуаций надо вообще что-то принципиально другое придумывать, чем суммы. Я взял твой код и попытался сделать следующие варианты замен:
N>1) вместо CRC — младшие 8 бит суммы байт
N>2) то же но с переносом старшего бита в конец (не XOR, а добавлением) (в стиле IP?)

N>Результат удручает — ни одна сумма такой ситуации не ловит. Статистически лучше всего, похоже, просто младший байт суммы всех байт потока, но тоже качество обнаружения отвратительное.


16-битная сумма в 256-байтном пакете (и более коротких) гарантированно ловит такие ситуации. Вроде ж очевидно. 16-битный CRC тоже их ловить не будет, хотя и с меньшей вероятностью.


fk0>> Это CRC с указанным полиномом и его результат для любых входных значений полностью совпадает с побитным алгоритмом CRC. Указанный полином на сайте smbus.org... Указанные коэффициенты для ксорки берутся из результатов вычисления таблицы CRC побитным алгоритмом и взятия каждого 2^N-го члена для N=0..7. Это оптимизированный алгоритм просто. И, кстати, на мелких контроллерах он может работать быстрее табличного (на гарвардских архитектурах доступ к данным в программной памяти -- медленный).

N>Я не про способ вычисления — понятно, что он подбирается под реализацию. А про собственно алгоритм. Впрочем, я уже нашёл как его логически описать: он эквивалентен классическому, но с добавлением ещё одного нулевого байта в конце входной последовательности.

Да он полностью эквиэвалентен. Я ж написал -- я налажал в коде. И написал как исправить.

fk0>> Увы и ах. Именно так, именно для того он и предназначен. И в RS-232 будет замечательно работать. А где пакетная передача с обрывами посереди пакета и заполнением конца пакета одинаковым битом -- не канает CRC.

N>Как уже сказал — там никакая сумма "не канает" пока нет подтверждения собственно целостности канала.

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

fk0>> Кстати ещё пример неправильного применения CRC -- контрольный код записи в FLASH-памяти. Догадываешься уже почему? Ровно та же проблема. Массовое FF-чивание отдельных блоков. Контрольная сумма подходящей разрядности (весьма небольшой) опять же справляется гарантировано и это очевидно математически.

N>Нет. Модифицируй свою программу и проверь: точно так же не справляется.

Это ж очевидно, что если в последовательности единиц и нулей часть последовательности заменить на единицы или нули, то сумма станет соответственно такой же или большей, или такой же (когда 0 заменяется на 0) или меньшей. Для одного разряда это так (проверь). И для каждого N+1 тоже (доказано). Если в сумме нет переполнений -- поэтому разрядность должна быть больше, чем log2(sum(все единицы)).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.