免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1830 | 回复: 0
打印 上一主题 下一主题

[算法] CRC循环校验的具体算法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-10 21:26 |只看该作者 |倒序浏览

  1. /**********************************************************************
  2. *
  3. * Filename: main.c
  4. *
  5. * Description: A simple test program for the CRC implementations.
  6. *
  7. * Notes: To test a different CRC standard, modify crc.h.
  8. *
  9. *
  10. * Copyright (c) 2000 by Michael Barr. This software is placed into
  11. * the public domain and may be used for any purpose. However, this
  12. * notice must not be changed or removed and no warranty is either
  13. * expressed or implied by its publication or distribution.
  14. **********************************************************************/


  15. #include <stdio.h>;
  16. #include <string.h>;

  17. #include "crc.h"


  18.     void
  19. main(void)
  20. {
  21.     unsigned char test[] = "123456789";


  22.     /*
  23.      * Print the check value for the selected CRC algorithm.
  24.      */
  25.     printf("The check value for the %s standard is 0x%X\n", CRC_NAME,
  26.             CHECK_VALUE);

  27.     /*
  28.      * Compute the CRC of the test message, slowly.
  29.      */
  30.     */
  31.         printf("The crcSlow() of \"123456789\" is 0x%X\n", crcSlow(test,
  32.                     strlen(test)));

  33.     /*
  34.      * Compute the CRC of the test message, more efficiently.
  35.      */
  36.     crcInit();
  37.     printf("The crcFast() of \"123456789\" is 0x%X\n", crcFast(test,
  38.                 strlen(test)));

  39. } /* main() */

  40. /**********************************************************************
  41. *
  42. * Filename: crc.h
  43. *
  44. * Description: A header file describing the various CRC standards.
  45. *
  46. * Notes:
  47. *
  48. *
  49. * Copyright (c) 2000 by Michael Barr. This software is placed into

  50. * the public domain and may be used for any purpose. However, this
  51. * notice must not be changed or removed and no warranty is either
  52. * expressed or implied by its publication or distribution.
  53. **********************************************************************/

  54. #ifndef _crc_h
  55. #define _crc_h


  56. #define FALSE 0
  57. #define TRUE !FALSE

  58. /*
  59. * Select the CRC standard from the list that follows.
  60. */
  61. #define CRC_CCITT


  62. #if defined(CRC_CCITT)

  63. typedef unsigned short crc;


  64. #define CRC_NAME "CRC-CCITT"
  65. #define POLYNOMIAL 0x1021
  66. #define INITIAL_REMAINDER 0xFFFF
  67. #define FINAL_XOR_VALUE 0x0000
  68. #define REFLECT_DATA FALSE
  69. #define REFLECT_REMAINDER FALSE
  70. #define CHECK_VALUE 0x29B1

  71. #elif defined(CRC16)

  72. typedef unsigned short crc;

  73. #define CRC_NAME "CRC-16"
  74. #define POLYNOMIAL 0x8005
  75. #define INITIAL_REMAINDER 0x0000
  76. #define FINAL_XOR_VALUE 0x0000
  77. #define REFLECT_DATA TRUE
  78. #define REFLECT_REMAINDER TRUE
  79. #define CHECK_VALUE 0xBB3D

  80. #elif defined(CRC32)


  81. typedef unsigned long crc;

  82. #define CRC_NAME "CRC-32"
  83. #define POLYNOMIAL 0x04C11DB7
  84. #define INITIAL_REMAINDER 0xFFFFFFFF
  85. #define FINAL_XOR_VALUE 0xFFFFFFFF
  86. #define REFLECT_DATA TRUE
  87. #define REFLECT_REMAINDER TRUE
  88. #define CHECK_VALUE 0xCBF43926

  89. #else

  90. #error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."

  91. #endif


  92. void crcInit(void);
  93. crc crcSlow(unsigned char const message[], int nBytes);
  94. crc crcFast(unsigned char const message[], int nBytes);



  95. #endif /* _crc_h */



  96. /**********************************************************************
  97. *
  98. * Filename: crc.c
  99. *
  100. * Description: Slow and fast implementations of the CRC standards.
  101. *
  102. * Notes: The parameters for each supported CRC standard are
  103. * defined in the header file crc.h. The implementtations
  104. * here should stand up to further additions to thaat list.
  105. *
  106. *
  107. * Copyright (c) 2000 by Michael Barr. This software is placed into
  108. * the public domain and may be used for any purpose. However, this
  109. * notice must not be changed or removed and no warranty is either
  110. * expressed or implied by its publication or distribution.
  111. **********************************************************************/

  112. #include "crc.h"
  113. #include "crc.h"


  114. /*
  115. * Derive parameters from the standard-specific parameters in crc.h.
  116. */
  117. #define WIDTH (8 * sizeof(crc))
  118. #define TOPBIT (1 << (WIDTH - 1))

  119. #if (REFLECT_DATA == TRUE)
  120. #undef REFLECT_DATA
  121. #define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
  122. #else
  123. #undef REFLECT_DATA
  124. #define REFLECT_DATA(X) (X)
  125. #endif

  126. #if (REFLECT_REMAINDER == TRUE)
  127. #undef REFLECT_REMAINDER
  128. #define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
  129. #else
  130. #undef REFLECT_REMAINDER
  131. #define REFLECT_REMAINDER(X) (X)

  132. #endif


  133. /*********************************************************************
  134. *
  135. * Function: reflect()
  136. *
  137. * Description: Reorder the bits of a binary sequence, by reflecting
  138. * them about the middle position.
  139. *
  140. * Notes: No checking is done that nBits <= 32.
  141. *
  142. * Returns: The reflection of the original data.
  143. *
  144. *********************************************************************/
  145.     static unsigned long
  146. reflect(unsigned long data, unsigned char nBits)
  147. {
  148.     unsigned long reflection = 0x00000000;
  149.     unsigned char bit;

  150.     /*
  151.     /*
  152.      * Reflect the data about the center bit.
  153.      */
  154.     for (bit = 0; bit < nBits; ++bit)
  155.     {
  156.         /*
  157.          * If the LSB bit is set, set the reflection of it.
  158.          */
  159.         if (data & 0x01)
  160.         {
  161.             reflection |= (1 << ((nBits - 1) - bit));
  162.         }

  163.         data = (data >;>; 1);
  164.     }

  165.     return (reflection);

  166. } /* reflect() */


  167. /*********************************************************************
  168. *
  169. *
  170. * Function: crcSlow()
  171. *
  172. * Description: Compute the CRC of a given message.
  173. *
  174. * Notes:
  175. *
  176. * Returns: The CRC of the message.
  177. *
  178. *********************************************************************/
  179.     crc
  180. crcSlow(unsigned char const message[], int nBytes)
  181. {
  182.     crc remainder = INITIAL_REMAINDER;
  183.     int byte;
  184.     unsigned char bit;


  185.     /*
  186.      * Perform modulo-2 division, a byte at a time.
  187.      */
  188.     for (byte = 0; byte < nBytes; ++byte)
  189.     {
  190.         {
  191.             /*
  192.              * Bring the next byte into the remainder.
  193.              */
  194.             remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));

  195.             /*
  196.              * Perform modulo-2 division, a bit at a time.
  197.              */
  198.             for (bit = 8; bit >; 0; --bit)
  199.             {
  200.                 /*
  201.                  * Try to divide the current data bit.
  202.                  */
  203.                 if (remainder & TOPBIT)
  204.                 {
  205.                     remainder = (remainder << 1) ^ POLYNOMIAL;
  206.                 }
  207.                 else
  208.                 {
  209.                     remainder = (remainder << 1);
  210.                 }
  211.             }
  212.         }
  213.     }

  214.     /*
  215.      * The final remainder is the CRC result.
  216.      */
  217.     return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);

  218. } /* crcSlow() */


  219. crc crcTable[256];


  220. /*********************************************************************
  221. *
  222. * Function: crcInit()
  223. *
  224. * Description: Populate the partial CRC lookup table.
  225. *
  226. * Notes: This function must be rerun any time the CRC standard
  227. * is changed. If desired, it can be run "offline"" and
  228. * the table results stored in an embedded system'ss ROM.

  229. *
  230. * Returns: None defined.
  231. *
  232. *********************************************************************/
  233.     void
  234. crcInit(void)
  235. {
  236.     crc remainder;
  237.     int dividend;
  238.     unsigned char bit;


  239.     /*
  240.      * Compute the remainder of each possible dividend.
  241.      */
  242.     for (dividend = 0; dividend < 256; ++dividend)
  243.     {
  244.         /*
  245.          * Start with the dividend followed by zeros.
  246.          */
  247.         remainder = dividend << (WIDTH - 8);


  248.         /*
  249.          * Perform modulo-2 division, a bit at a time.
  250.          */
  251.         for (bit = 8; bit >; 0; --bit)
  252.         {
  253.             /*
  254.              * Try to divide the current data bit.
  255.              */
  256.             if (remainder & TOPBIT)
  257.             {
  258.                 remainder = (remainder << 1) ^ POLYNOMIAL;
  259.             }
  260.             else
  261.             {
  262.                 remainder = (remainder << 1);
  263.             }
  264.         }

  265.         /*
  266.          * Store the result into the table.
  267.          */
  268.         crcTable[dividend] = remainder;

  269.     }

  270. } /* crcInit() */


  271. /*********************************************************************
  272. *
  273. * Function: crcFast()
  274. *
  275. * Description: Compute the CRC of a given message.
  276. *
  277. * Notes: crcInit() must be called first.
  278. *
  279. * Returns: The CRC of the message.
  280. *
  281. *********************************************************************/
  282.     crc
  283. crcFast(unsigned char const message[], int nBytes)
  284. {
  285.     crc remainder = INITIAL_REMAINDER;
  286.     unsigned char data;
  287.     int byte;
  288.     int byte;


  289.     /*
  290.      * Divide the message by the polynomial, a byte at a time.
  291.      */
  292.     for (byte = 0; byte < nBytes; ++byte)
  293.     {
  294.         data = REFLECT_DATA(message[byte]) ^ (remainder >;>; (WIDTH - 8));
  295.         remainder = crcTable[data] ^ (remainder << 8);
  296.     }

  297.     /*
  298.      * The final remainder is the CRC.
  299.      */
  300.     return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);

  301. } /* crcFast() */
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP