home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_09 / 8n09063a < prev    next >
Text File  |  1990-07-24  |  4KB  |  120 lines

  1.  
  2. /*
  3. //      LISTING 1
  4. */
  5.  
  6.  
  7. /****************************************************************************
  8. //
  9. // crc16.c - generate a ccitt 16 bit cyclic redundancy check (crc)
  10. //
  11. //      The code in this module generates the crc for a block of data.
  12. //
  13. ****************************************************************************/
  14.  
  15.  
  16. /*
  17. //                                 16   12   5
  18. // The CCITT CRC 16 polynomial is X  + X  + X  + 1.
  19. // In binary, this is the bit pattern 1 0001 0000 0010 0001, and in hex it
  20. //  is 0x11021.
  21. // A 17 bit register is simulated by testing the MSB before shifting 
  22. //  the data, which affords us the luxury of specifiy the polynomial as a
  23. //  16 bit value, 0x1021.
  24. // Due to the way in which we process the CRC, the bits of the polynomial
  25. //  are stored in reverse order. This makes the polynomial 0x8408.
  26. */
  27. #define POLY 0x8408     
  28.  
  29.  
  30. /* 
  31. // note: when the crc is included in the message, the valid crc is:
  32. //      0xF0B8, before the compliment and byte swap,
  33. //      0x0F47, after compliment, before the byte swap,
  34. //      0x470F, after the compliment and the byte swap.
  35. */
  36.  
  37. extern  crc_ok;
  38. int     crc_ok = 0x470F;
  39.  
  40. /****************************************************************************
  41. //
  42. // crc16() - generate a 16 bit crc
  43. //
  44. //
  45. // PURPOSE
  46. //      This routine generates the 16 bit remainder of a block of
  47. //      data using the ccitt polynomial generator.
  48. //
  49. // CALLING SEQUENCE
  50. //      crc = crc16(data, len);
  51. //
  52. // PARAMETERS
  53. //      data    <-- address of start of data block
  54. //      len     <-- length of data block
  55. //
  56. // RETURNED VALUE
  57. //      crc16 value. data is calcuated using the 16 bit ccitt polynomial.
  58. //
  59. // NOTES
  60. //      The CRC is preset to all 1's to detect errors involving a loss
  61. //        of leading zero's.
  62. //      The CRC (a 16 bit value) is generated in LSB MSB order.
  63. //      Two ways to verify the integrity of a received message 
  64. //        or block of data:
  65. //        1) Calculate the crc on the data, and compare it to the crc 
  66. //           calculated previously. The location of the saved crc must be 
  67. //           known.
  68. //        2) Append the calculated crc to the end of the data. Now calculate 
  69. //           the crc of the data and its crc. If the new crc equals the 
  70. //           value in "crc_ok", the data is valid.
  71. //
  72. // PSEUDO CODE:
  73. //      initialize crc (-1)
  74. //      DO WHILE count NE zero
  75. //        DO FOR each bit in the data byte, from LSB to MSB
  76. //          IF (LSB of crc) EOR (LSB of data)
  77. //            crc := (crc / 2) EOR polynomial
  78. //          ELSE
  79. //            crc := (crc / 2)
  80. //          FI
  81. //        OD
  82. //      OD
  83. //      1's compliment and swap bytes in crc
  84. //      RETURN crc
  85. //
  86. ****************************************************************************/
  87.  
  88. unsigned short crc16(data_p, length)
  89. char *data_p;
  90. unsigned short length;
  91. {
  92.         unsigned char   i;
  93.         unsigned int data;
  94.         unsigned int crc;
  95.                 
  96.         crc = 0xffff;
  97.         
  98.         if (length == 0)
  99.                 return (~crc);
  100.         
  101.         do {
  102.                 for (i = 0, data = (unsigned int)0xff & *data_p++;
  103.                      i < 8;
  104.                      i++, data >>= 1) {
  105.                         if ((crc & 0x0001) ^ (data & 0x0001))
  106.                                 crc = (crc >> 1) ^ POLY;
  107.                         else
  108.                                 crc >>= 1;
  109.                 }
  110.         } while (--length);
  111.         
  112.         crc = ~crc;
  113.         
  114.         data = crc;
  115.         crc = (crc << 8) | (data >> 8 & 0xFF);
  116.                 
  117.         return (crc);
  118. }
  119.  
  120.