Расчет CRC - PullRequest
       7

Расчет CRC

4 голосов
/ 23 февраля 2009

Я пытаюсь взаимодействовать со сторонней системой, и они предоставили пример кода для вычисления значения CRC при отправке текстовых данных.

Код C, предоставленный поставщиком, выглядит следующим образом:

#define CRCRES 0xf0b8  /* residue for good verify */ 
#define DEBUG 

unsigned crctbl[] = {0x0000, 0x1081, 0x2102, 0x3183, 
                     0x4204, 0x5285, 0x6306, 0x7387, 
                     0x8408, 0x9489, 0xa50a, 0xb58b, 
                     0xc60c, 0xd68d, 0xe70e, 0xf78f}; 

/* 
 * This uses a 32 byte table to lookup the crc 4 bits at a time. 
 * The CRC CCITT is used. 
 */ 


unsigned short calc_crc(unsigned char *ptr, unsigned length) 

{ 
  unsigned short crc; 
  unsigned short i; 
  unsigned char pos,ch; 

  crc = 0xffff;  /* precondition crc */ 
  for (i = 0; i < length; i++,ptr++) { 
    ch = *ptr; 
    pos = (crc ^ ch) & 15; 
    crc = ((crc >> 4) & 0x0fff) ^ crctbl[pos]; 
    ch >>= 4; 
    pos = (crc^ch) & 15; 
    crc = ((crc >> 4) & 0xffff) ^ crctbl[pos]; 
  } 
  crc = ~crc;  /* post condition */ 
  crc = (crc << 8) | (crc >> 8); /* bytewise reverse */ 
  return crc; 
} 


/* 
 * tests the block of code containing the crc to verify it's 
 * content.  This compares to the reversed and inverted 
 * residue. 
 */ 

int test_crc(unsigned char *ptr, unsigned length) 

{ 
  unsigned short crc; 
  unsigned char arr [] = {'X','Y','Z'}; 

  crc = calc_crc(arr,3); 
  printf("Calced crc of test to be %04x, (should be 470f)\n", crc); 
  return (crc == 0x470f); 
} 

Я скопировал этот код и вставил пример программы на Си. Метод test_crc не рассчитывает значение CRC, равное 470f (он рассчитывается как DD7A).

Я надеюсь, что кто-то может либо проверить, что этот код не работает, как говорит производитель, или помочь мне получить test_crc для возврата правильного значения.

Спасибо за помощь.

Ответы [ 3 ]

4 голосов
/ 24 февраля 2009

Проблема решена. Спецификации от продавца были неверны. Правильная контрольная сумма для XYZ - DD7A. Документация была неверной.

Добавьте это к тому факту, что ранее на странице, когда они объясняли, какие данные передавать методу calc_crc для получения crc для фактического сообщения, также неправильно, это делало его сложным проектом.

Спасибо за помощь.

3 голосов
/ 23 февраля 2009

Расчет, как оказалось, не показывает никакой ошибки, которая приходит мне в голову. Просто еще раз рассмотрите алгоритм. В частности, ища возможные проблемы, обратите внимание, что константы, которые аннулируются в разных частях алгоритма, это 0x0fff и 0xffff. Может быть, 0x0fff и 0xfff0 должны быть более симметричными ... Иногда мы думаем, что настоящая проблема может быть из другого места, и забываем перепроверить очевидные вещи ...:)

2 голосов
/ 23 февраля 2009

Аппаратные платформы одинаковы? Может быть, у вас другая последовательность (У вас x86, например, 68000 процессоров.)

...