Вычисление CRC в C

У меня есть устройство, которое отправляет мне данные с вычислением CRC. Каждые 16 байтов содержат 2 байта CRC. Порождающий полином равен x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1.

Мой код выглядит так:

int crc16(unsigned char *addr, int num, int crc)
{
    uint16_t poly = 0x3D65;
    int i;
    for (; num > 0; num--)           /* Step through bytes in memory */
    {
        crc = crc ^ ((unsigned short)*addr++ << 8);         /* Fetch byte from memory, XOR into  CRC top byte*/
        for (i = 0; i < 8; i++)      /* Prepare to rotate 8 bits */
        {
            if (crc & 0x10000)       /* b15 is set... */
                crc = (crc << 1) ^ poly;    /* rotate and XOR with XMODEM polynomic */
            else                     /* b15 is clear... */
                crc <<= 1;           /* just rotate */
        }                            /* Loop for 8 bits */
        crc &= 0xFFFF;               /* Ensure CRC remains 16-bit value */
     }                               /* Loop until num=0 */
     return(crc);                    /* Return updated CRC */
}

Я также пробовал этот код с другими полиномами, такими как 0x9CB2. Я думаю, что в коде есть ошибка.


c crc
person hp58    schedule 31.05.2012    source источник
comment
И ваш вопрос....что именно?   -  person paxdiablo    schedule 31.05.2012
comment
Не могли бы вы уточнить вопрос, пожалуйста? подскажите где именно проблема...   -  person felixgaal    schedule 31.05.2012
comment
Итак, вы думаете, что в коде есть ошибка. Но почему вы так думаете? Что именно не работает? Какие неправильные результаты вы получаете?   -  person Thomas Padron-McCarthy    schedule 31.05.2012
comment
Почему вы храните байт в 16-битном и XOR с байтом ms? Мне это кажется очень странным.   -  person Lundin    schedule 31.05.2012
comment
Как документация устройства описывает CRC, кроме полинома? Биты CRC могут быть сохранены в любом порядке, может быть начальное значение, отличное от нуля, и может быть предварительная и/или постобработка. Вы должны прочитать ross.net/crc/download/crc_v3.txt .   -  person Mark Adler    schedule 01.06.2012
comment
Можете ли вы привести пример 16 байтов данных и 2-байтовой контрольной суммы с устройства?   -  person Mark Adler    schedule 01.06.2012
comment
Можете ли вы получить онлайн-калькулятор CRC в реальном времени, чтобы сгенерировать тот же CRC, что и ваше устройство?   -  person David Cary    schedule 02.05.2013


Ответы (1)


Какой компилятор/платформу вы используете? Вы уверены, что тип данных int 32-битный? Попробуйте с long и сравните результаты.

Кроме того, есть пункт, в котором вы делаете следующее, если:

if ( crc & 0x10000 )

и в комментарии вы заявляете, что проверяете 15-й бит. Нет, это не так, вы будете проверять 16-й бит. Для 15-го это будет ( crc & 0x8000 ).

person felixgaal    schedule 31.05.2012
comment
Или просто напишите if(crc >> 15), чтобы стало понятно, что делает код. - person Lundin; 31.05.2012
comment
И да и нет. У меня сложилось впечатление, что платформа, на которой будет выполняться этот код, представляет собой микропроцессор во встроенном устройстве. Если это так, && является атомарным (один цикл ЦП). Ваше предложение верно на 100%, но на некоторых аппаратных средствах это будет означать 15 циклов процессора. А если процессор имеет разрядность 8 бит... вы можете себе представить! - person felixgaal; 31.05.2012
comment
Компилятор, скорее всего, сможет оптимизировать код на таких платформах. - person Lundin; 31.05.2012
comment
Скорее всего, не. Я использую для программирования такие устройства, и оптимизация обычно отключена для большего контроля над временными задержками и постоянным временем выполнения. - person felixgaal; 31.05.2012
comment
Эм... нет? Я постоянно программирую такие системы. Только любители полагаются на циклы задержки на основе кода операции, профессионалы используют встроенные аппаратные таймеры, так что это даже не проблема. Что касается постоянного времени выполнения, то как только вы закончите работать с исходным файлом, компилятор каждый раз будет оптимизировать код одинаково. Я только что сделал тест со старым компилятором для 16-битного MCU, и он оптимизировал правый сдвиг для проверки на 0x8000, как я и ожидал. 8-битные, вероятно, будут плохо работать с любым 16-битным CRC, в этом конкретном случае я бы использовал таблицу поиска для CRC. - person Lundin; 31.05.2012
comment
Я полагаю, мы используем разные среды разработки. Я программирую 8-битные микропроцессоры с низкой частотой. оск. и эти оптимизации не всегда в моем распоряжении. И позвольте мне сказать вам, что есть любители, которые программируют намного лучше, чем те, кто изображает из себя настоящих профессионалов. Профессионалы И любители работают на C и на ассемблере, с оптимизацией или без, и не боятся этого. Мой предыдущий комментарий был конструктивным, а не деструктивным. Я больше не буду комментировать этот вопрос, так как он нагревается. Здесь не место для этого. - person felixgaal; 31.05.2012