crc.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /**********************************************************************
  2. *
  3. * Filename: crc.c
  4. *
  5. * Description: Slow and fast implementations of the CRC standards.
  6. *
  7. * Notes: The parameters for each supported CRC standard are
  8. * defined in the header file crc.h. The implementations
  9. * here should stand up to further additions to that list.
  10. *
  11. *
  12. * Copyright (c) 2000 by Michael Barr. This software is placed into
  13. * the public domain and may be used for any purpose. However, this
  14. * notice must not be changed or removed and no warranty is either
  15. * expressed or implied by its publication or distribution.
  16. **********************************************************************/
  17. #include "crc.h"
  18. /*
  19. * Derive parameters from the standard-specific parameters in crc.h.
  20. */
  21. #define WIDTH (8 * sizeof(crc))
  22. #define TOPBIT (1 << (WIDTH - 1))
  23. #if (REFLECT_DATA == TRUE)
  24. #undef REFLECT_DATA
  25. #define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
  26. #else
  27. #undef REFLECT_DATA
  28. #define REFLECT_DATA(X) (X)
  29. #endif
  30. #if (REFLECT_REMAINDER == TRUE)
  31. #undef REFLECT_REMAINDER
  32. #define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
  33. #else
  34. #undef REFLECT_REMAINDER
  35. #define REFLECT_REMAINDER(X) (X)
  36. #endif
  37. /*********************************************************************
  38. *
  39. * Function: reflect()
  40. *
  41. * Description: Reorder the bits of a binary sequence, by reflecting
  42. * them about the middle position.
  43. *
  44. * Notes: No checking is done that nBits <= 32.
  45. *
  46. * Returns: The reflection of the original data.
  47. *
  48. *********************************************************************/
  49. static unsigned long
  50. reflect(unsigned long data, unsigned char nBits)
  51. {
  52. unsigned long reflection = 0x00000000;
  53. unsigned char bit;
  54. /*
  55. * Reflect the data about the center bit.
  56. */
  57. for (bit = 0; bit < nBits; ++bit)
  58. {
  59. /*
  60. * If the LSB bit is set, set the reflection of it.
  61. */
  62. if (data & 0x01)
  63. {
  64. reflection |= (1 << ((nBits - 1) - bit));
  65. }
  66. data = (data >> 1);
  67. }
  68. return (reflection);
  69. } /* reflect() */
  70. /*********************************************************************
  71. *
  72. * Function: crcSlow()
  73. *
  74. * Description: Compute the CRC of a given message.
  75. *
  76. * Notes:
  77. *
  78. * Returns: The CRC of the message.
  79. *
  80. *********************************************************************/
  81. crc
  82. crcSlow(unsigned char const message[], int nBytes)
  83. {
  84. crc remainder = INITIAL_REMAINDER;
  85. int byte;
  86. unsigned char bit;
  87. /*
  88. * Perform modulo-2 division, a byte at a time.
  89. */
  90. for (byte = 0; byte < nBytes; ++byte)
  91. {
  92. /*
  93. * Bring the next byte into the remainder.
  94. */
  95. remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
  96. /*
  97. * Perform modulo-2 division, a bit at a time.
  98. */
  99. for (bit = 8; bit > 0; --bit)
  100. {
  101. /*
  102. * Try to divide the current data bit.
  103. */
  104. if (remainder & TOPBIT)
  105. {
  106. remainder = (remainder << 1) ^ POLYNOMIAL;
  107. }
  108. else
  109. {
  110. remainder = (remainder << 1);
  111. }
  112. }
  113. }
  114. /*
  115. * The final remainder is the CRC result.
  116. */
  117. return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
  118. } /* crcSlow() */
  119. crc crcTable[256];
  120. /*********************************************************************
  121. *
  122. * Function: crcInit()
  123. *
  124. * Description: Populate the partial CRC lookup table.
  125. *
  126. * Notes: This function must be rerun any time the CRC standard
  127. * is changed. If desired, it can be run "offline" and
  128. * the table results stored in an embedded system's ROM.
  129. *
  130. * Returns: None defined.
  131. *
  132. *********************************************************************/
  133. void
  134. crcInit(void)
  135. {
  136. crc remainder;
  137. int dividend;
  138. unsigned char bit;
  139. /*
  140. * Compute the remainder of each possible dividend.
  141. */
  142. for (dividend = 0; dividend < 256; ++dividend)
  143. {
  144. /*
  145. * Start with the dividend followed by zeros.
  146. */
  147. remainder = dividend << (WIDTH - 8);
  148. /*
  149. * Perform modulo-2 division, a bit at a time.
  150. */
  151. for (bit = 8; bit > 0; --bit)
  152. {
  153. /*
  154. * Try to divide the current data bit.
  155. */
  156. if (remainder & TOPBIT)
  157. {
  158. remainder = (remainder << 1) ^ POLYNOMIAL;
  159. }
  160. else
  161. {
  162. remainder = (remainder << 1);
  163. }
  164. }
  165. /*
  166. * Store the result into the table.
  167. */
  168. crcTable[dividend] = remainder;
  169. }
  170. } /* crcInit() */
  171. /*********************************************************************
  172. *
  173. * Function: crcFast()
  174. *
  175. * Description: Compute the CRC of a given message.
  176. *
  177. * Notes: crcInit() must be called first.
  178. *
  179. * Returns: The CRC of the message.
  180. *
  181. *********************************************************************/
  182. crc
  183. crcFast(unsigned char const message[], int nBytes)
  184. {
  185. crc remainder = INITIAL_REMAINDER;
  186. unsigned char data;
  187. int byte;
  188. /*
  189. * Divide the message by the polynomial, a byte at a time.
  190. */
  191. for (byte = 0; byte < nBytes; ++byte)
  192. {
  193. data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
  194. remainder = crcTable[data] ^ (remainder << 8);
  195. }
  196. /*
  197. * The final remainder is the CRC.
  198. */
  199. return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
  200. } /* crcFast() */