分享

CRC校验码生成与数据校验源码程序 (包括CRC

 yxz1212_bao 2017-04-12
  1. Python有个库,好像可以根据配置参数自动生成各种CRC校验的C语言代码,会用的可以去用一下.  
  1. /****************************************************************************** 
  2.  * Name:    CRC-4/ITU           x4+x+1 
  3.  * Poly:    0x03 
  4.  * Init:    0x00 
  5.  * Refin:   True 
  6.  * Refout:  True 
  7.  * Xorout:  0x00 
  8.  * Note: 
  9.  *****************************************************************************/  
  10. uint8_t crc4_itu(uint8_t *data, uint_len length)  
  11. {  
  12.     uint8_t i;  
  13.     uint8_t crc = 0;        // Initial value  
  14.     while(length--)  
  15.     {  
  16.         crc ^= *data++;     // crc ^= *data; data++;  
  17.         for (i = 0; i < 8; ++i)  
  18.         {  
  19.             if (crc & 1)  
  20.                 crc = (crc >> 1) ^ 0x0C;// 0x0C = (reverse 0x03)>>(8-4)  
  21.             else  
  22.                 crc = (crc >> 1);  
  23.         }  
  24.     }  
  25.     return crc;  
  26. }  
  27.   
  28. /****************************************************************************** 
  29.  * Name:    CRC-5/EPC           x5+x3+1 
  30.  * Poly:    0x09 
  31.  * Init:    0x09 
  32.  * Refin:   False 
  33.  * Refout:  False 
  34.  * Xorout:  0x00 
  35.  * Note: 
  36.  *****************************************************************************/  
  37. uint8_t crc5_epc(uint8_t *data, uint_len length)  
  38. {  
  39.     uint8_t i;  
  40.     uint8_t crc = 0x48; // Initial value: 0x48 = 0x09<<(8-5)  
  41.     while(length--)  
  42.     {  
  43.         crc ^= *data++; // crc ^= *data; data++;  
  44.         for ( i = 0; i < 8; i++ )  
  45.         {  
  46.             if ( crc & 0x80 )  
  47.                 crc = (crc << 1) ^ 0x48;  // 0x48 = 0x09<<(8-5)  
  48.             else  
  49.                 crc <<= 1;  
  50.         }  
  51.     }  
  52.     return crc >> 3;  
  53. }  
  54.   
  55. /****************************************************************************** 
  56.  * Name:    CRC-5/ITU           x5+x4+x2+1 
  57.  * Poly:    0x15 
  58.  * Init:    0x00 
  59.  * Refin:   True 
  60.  * Refout:  True 
  61.  * Xorout:  0x00 
  62.  * Note: 
  63.  *****************************************************************************/  
  64. uint8_t crc5_itu(uint8_t *data, uint_len length)  
  65. {  
  66.     uint8_t i;  
  67.     uint8_t crc = 0;        // Initial value  
  68.     while(length--)  
  69.     {  
  70.         crc ^= *data++;     // crc ^= *data; data++;  
  71.         for (i = 0; i < 8; ++i)  
  72.         {  
  73.             if (crc & 1)  
  74.                 crc = (crc >> 1) ^ 0x15;// 0x15 = (reverse 0x15)>>(8-5)  
  75.             else  
  76.                 crc = (crc >> 1);  
  77.         }  
  78.     }  
  79.     return crc;  
  80. }  
  81.   
  82. /****************************************************************************** 
  83.  * Name:    CRC-5/USB           x5+x2+1 
  84.  * Poly:    0x05 
  85.  * Init:    0x1F 
  86.  * Refin:   True 
  87.  * Refout:  True 
  88.  * Xorout:  0x1F 
  89.  * Note: 
  90.  *****************************************************************************/  
  91. uint8_t crc5_usb(uint8_t *data, uint_len length)  
  92. {  
  93.     uint8_t i;  
  94.     uint8_t crc = 0x1F;     // Initial value  
  95.     while(length--)  
  96.     {  
  97.         crc ^= *data++;     // crc ^= *data; data++;  
  98.         for (i = 0; i < 8; ++i)  
  99.         {  
  100.             if (crc & 1)  
  101.                 crc = (crc >> 1) ^ 0x14;// 0x14 = (reverse 0x05)>>(8-5)  
  102.             else  
  103.                 crc = (crc >> 1);  
  104.         }  
  105.     }  
  106.     return crc ^ 0x1F;  
  107. }  
  108.   
  109. /****************************************************************************** 
  110.  * Name:    CRC-6/ITU           x6+x+1 
  111.  * Poly:    0x03 
  112.  * Init:    0x00 
  113.  * Refin:   True 
  114.  * Refout:  True 
  115.  * Xorout:  0x00 
  116.  * Note: 
  117.  *****************************************************************************/  
  118. uint8_t crc6_itu(uint8_t *data, uint_len length)  
  119. {  
  120.     uint8_t i;  
  121.     uint8_t crc = 0;    // Initial value  
  122.     while(length--)  
  123.     {  
  124.         crc ^= *data++; // crc ^= *data; data++;  
  125.         for (i = 0; i < 8; ++i)  
  126.         {  
  127.             if (crc & 1)  
  128.                 crc = (crc >> 1) ^ 0x30;// 0x30 = (reverse 0x03)>>(8-6)  
  129.             else  
  130.                 crc = (crc >> 1);  
  131.         }  
  132.     }  
  133.     return crc;  
  134. }  
  135.   
  136. /****************************************************************************** 
  137.  * Name:    CRC-7/MMC           x7+x3+1 
  138.  * Poly:    0x09 
  139.  * Init:    0x00 
  140.  * Refin:   False 
  141.  * Refout:  False 
  142.  * Xorout:  0x00 
  143.  * Use:     MultiMediaCard,SD,ect. 
  144.  *****************************************************************************/  
  145. uint8_t crc7_mmc(uint8_t *data, uint_len length)  
  146. {  
  147.     uint8_t i;  
  148.     uint8_t crc = 0;    // Initial value  
  149.     while(length--)  
  150.     {  
  151.         crc ^= *data++; // crc ^= *data; data++;  
  152.         for ( i = 0; i < 8; i++ )  
  153.         {  
  154.             if ( crc & 0x80 )  
  155.                 crc = (crc << 1) ^ 0x12;  // 0x12 = 0x09<<(8-7)  
  156.             else  
  157.                 crc <<= 1;  
  158.         }  
  159.     }  
  160.     return crc >> 1;  
  161. }  
  162.   
  163. /****************************************************************************** 
  164.  * Name:    CRC-8               x8+x2+x+1 
  165.  * Poly:    0x07 
  166.  * Init:    0x00 
  167.  * Refin:   False 
  168.  * Refout:  False 
  169.  * Xorout:  0x00 
  170.  * Note: 
  171.  *****************************************************************************/  
  172. uint8_t crc8(uint8_t *data, uint_len length)  
  173. {  
  174.     uint8_t i;  
  175.     uint8_t crc = 0;    // Initial value  
  176.     while(length--)  
  177.     {  
  178.         crc ^= *data++; // crc ^= *data; data++;  
  179.         for ( i = 0; i < 8; i++ )  
  180.         {  
  181.             if ( crc & 0x80 )  
  182.                 crc = (crc << 1) ^ 0x07;  
  183.             else  
  184.                 crc <<= 1;  
  185.         }  
  186.     }  
  187.     return crc;  
  188. }  
  189.   
  190. /****************************************************************************** 
  191.  * Name:    CRC-8/ITU           x8+x2+x+1 
  192.  * Poly:    0x07 
  193.  * Init:    0x00 
  194.  * Refin:   False 
  195.  * Refout:  False 
  196.  * Xorout:  0x55 
  197.  * Alias:   CRC-8/ATM 
  198.  *****************************************************************************/  
  199. uint8_t crc8_itu(uint8_t *data, uint_len length)  
  200. {  
  201.     uint8_t i;  
  202.     uint8_t crc = 0;    // Initial value  
  203.     while(length--)  
  204.     {  
  205.         crc ^= *data++; // crc ^= *data; data++;  
  206.         for ( i = 0; i < 8; i++ )  
  207.         {  
  208.             if ( crc & 0x80 )  
  209.                 crc = (crc << 1) ^ 0x07;  
  210.             else  
  211.                 crc <<= 1;  
  212.         }  
  213.     }  
  214.     return crc ^ 0x55;  
  215. }  
  216.   
  217. /****************************************************************************** 
  218.  * Name:    CRC-8/ROHC          x8+x2+x+1 
  219.  * Poly:    0x07 
  220.  * Init:    0xFF 
  221.  * Refin:   True 
  222.  * Refout:  True 
  223.  * Xorout:  0x00 
  224.  * Note: 
  225.  *****************************************************************************/  
  226. uint8_t crc8_rohc(uint8_t *data, uint_len length)  
  227. {  
  228.     uint8_t i;  
  229.     uint8_t crc = 0xFF;     // Initial value  
  230.     while(length--)  
  231.     {  
  232.         crc ^= *data++;     // crc ^= *data; data++;  
  233.         for (i = 0; i < 8; ++i)  
  234.         {  
  235.             if (crc & 1)  
  236.                 crc = (crc >> 1) ^ 0xE0;  // 0xE0 = reverse 0x07  
  237.             else  
  238.                 crc = (crc >> 1);  
  239.         }  
  240.     }  
  241.     return crc;  
  242. }  
  243.   
  244. /****************************************************************************** 
  245.  * Name:    CRC-8/MAXIM         x8+x5+x4+1 
  246.  * Poly:    0x31 
  247.  * Init:    0x00 
  248.  * Refin:   True 
  249.  * Refout:  True 
  250.  * Xorout:  0x00 
  251.  * Alias:   DOW-CRC,CRC-8/IBUTTON 
  252.  * Use:     Maxim(Dallas)'s some devices,e.g. DS18B20 
  253.  *****************************************************************************/  
  254. uint8_t crc8_maxim(uint8_t *data, uint_len length)  
  255. {  
  256.     uint8_t i;  
  257.     uint8_t crc = 0;    // Initial value  
  258.     while(length--)  
  259.     {  
  260.         crc ^= *data++; // crc ^= *data; data++;  
  261.         for (i = 0; i < 8; i++)  
  262.         {  
  263.             if (crc & 1)  
  264.                 crc = (crc >> 1) ^ 0x8C;  // 0x8C = reverse 0x31  
  265.             else  
  266.                 crc >>= 1;  
  267.         }  
  268.     }  
  269.     return crc;  
  270. }  
  271.   
  272. /****************************************************************************** 
  273.  * Name:    CRC-16/IBM          x16+x15+x2+1 
  274.  * Poly:    0x8005 
  275.  * Init:    0x0000 
  276.  * Refin:   True 
  277.  * Refout:  True 
  278.  * Xorout:  0x0000 
  279.  * Alias:   CRC-16,CRC-16/ARC,CRC-16/LHA 
  280.  *****************************************************************************/  
  281. uint16_t crc16_ibm(uint8_t *data, uint_len length)  
  282. {  
  283.     uint8_t i;  
  284.     uint16_t crc = 0;   // Initial value  
  285.     while(length--)  
  286.     {  
  287.         crc ^= *data++; // crc ^= *data; data++;  
  288.         for (i = 0; i < 8; ++i)  
  289.         {  
  290.             if (crc & 1)  
  291.                 crc = (crc >> 1) ^ 0xA001;    // 0xA001 = reverse 0x8005  
  292.             else  
  293.                 crc = (crc >> 1);  
  294.         }  
  295.     }  
  296.     return crc;  
  297. }  
  298.   
  299. /****************************************************************************** 
  300.  * Name:    CRC-16/MAXIM        x16+x15+x2+1 
  301.  * Poly:    0x8005 
  302.  * Init:    0x0000 
  303.  * Refin:   True 
  304.  * Refout:  True 
  305.  * Xorout:  0xFFFF 
  306.  * Note: 
  307.  *****************************************************************************/  
  308. uint16_t crc16_maxim(uint8_t *data, uint_len length)  
  309. {  
  310.     uint8_t i;  
  311.     uint16_t crc = 0;   // Initial value  
  312.     while(length--)  
  313.     {  
  314.         crc ^= *data++; // crc ^= *data; data++;  
  315.         for (i = 0; i < 8; ++i)  
  316.         {  
  317.             if (crc & 1)  
  318.                 crc = (crc >> 1) ^ 0xA001;    // 0xA001 = reverse 0x8005  
  319.             else  
  320.                 crc = (crc >> 1);  
  321.         }  
  322.     }  
  323.     return ~crc;    // crc^0xffff  
  324. }  
  325.   
  326. /****************************************************************************** 
  327.  * Name:    CRC-16/USB          x16+x15+x2+1 
  328.  * Poly:    0x8005 
  329.  * Init:    0xFFFF 
  330.  * Refin:   True 
  331.  * Refout:  True 
  332.  * Xorout:  0xFFFF 
  333.  * Note: 
  334.  *****************************************************************************/  
  335. uint16_t crc16_usb(uint8_t *data, uint_len length)  
  336. {  
  337.     uint8_t i;  
  338.     uint16_t crc = 0xffff;  // Initial value  
  339.     while(length--)  
  340.     {  
  341.         crc ^= *data++;     // crc ^= *data; data++;  
  342.         for (i = 0; i < 8; ++i)  
  343.         {  
  344.             if (crc & 1)  
  345.                 crc = (crc >> 1) ^ 0xA001;    // 0xA001 = reverse 0x8005  
  346.             else  
  347.                 crc = (crc >> 1);  
  348.         }  
  349.     }  
  350.     return ~crc;    // crc^0xffff  
  351. }  
  352.   
  353. /****************************************************************************** 
  354.  * Name:    CRC-16/MODBUS       x16+x15+x2+1 
  355.  * Poly:    0x8005 
  356.  * Init:    0xFFFF 
  357.  * Refin:   True 
  358.  * Refout:  True 
  359.  * Xorout:  0x0000 
  360.  * Note: 
  361.  *****************************************************************************/  
  362. uint16_t crc16_modbus(uint8_t *data, uint_len length)  
  363. {  
  364.     uint8_t i;  
  365.     uint16_t crc = 0xffff;  // Initial value  
  366.     while(length--)  
  367.     {  
  368.         crc ^= *data++;     // crc ^= *data; data++;  
  369.         for (i = 0; i < 8; ++i)  
  370.         {  
  371.             if (crc & 1)  
  372.                 crc = (crc >> 1) ^ 0xA001;    // 0xA001 = reverse 0x8005  
  373.             else  
  374.                 crc = (crc >> 1);  
  375.         }  
  376.     }  
  377.     return crc;  
  378. }  
  379.   
  380. /****************************************************************************** 
  381.  * Name:    CRC-16/CCITT        x16+x12+x5+1 
  382.  * Poly:    0x1021 
  383.  * Init:    0x0000 
  384.  * Refin:   True 
  385.  * Refout:  True 
  386.  * Xorout:  0x0000 
  387.  * Alias:   CRC-CCITT,CRC-16/CCITT-TRUE,CRC-16/KERMIT 
  388.  *****************************************************************************/  
  389. uint16_t crc16_ccitt(uint8_t *data, uint_len length)  
  390. {  
  391.     uint8_t i;  
  392.     uint16_t crc = 0;   // Initial value  
  393.     while(length--)  
  394.     {  
  395.         crc ^= *data++; // crc ^= *data; data++;  
  396.         for (i = 0; i < 8; ++i)  
  397.         {  
  398.             if (crc & 1)  
  399.                 crc = (crc >> 1) ^ 0x8408;    // 0x8408 = reverse 0x1021  
  400.             else  
  401.                 crc = (crc >> 1);  
  402.         }  
  403.     }  
  404.     return crc;  
  405. }  
  406.   
  407. /****************************************************************************** 
  408.  * Name:    CRC-16/CCITT-FALSE   x16+x12+x5+1 
  409.  * Poly:    0x1021 
  410.  * Init:    0xFFFF 
  411.  * Refin:   False 
  412.  * Refout:  False 
  413.  * Xorout:  0x0000 
  414.  * Note: 
  415.  *****************************************************************************/  
  416. uint16_t crc16_ccitt_false(uint8_t *data, uint_len length)  
  417. {  
  418.     uint8_t i;  
  419.     uint16_t crc = 0xffff;  //Initial value  
  420.     while(length--)  
  421.     {  
  422.         crc ^= (uint16_t)(*data++) << 8; // crc ^= (uint6_t)(*data)<<8; data++;  
  423.         for (i = 0; i < 8; ++i)  
  424.         {  
  425.             if ( crc & 0x8000 )  
  426.                 crc = (crc << 1) ^ 0x1021;  
  427.             else  
  428.                 crc <<= 1;  
  429.         }  
  430.     }  
  431.     return crc;  
  432. }  
  433.   
  434. /****************************************************************************** 
  435.  * Name:    CRC-16/X25          x16+x12+x5+1 
  436.  * Poly:    0x1021 
  437.  * Init:    0xFFFF 
  438.  * Refin:   True 
  439.  * Refout:  True 
  440.  * Xorout:  0XFFFF 
  441.  * Note: 
  442.  *****************************************************************************/  
  443. uint16_t crc16_x25(uint8_t *data, uint_len length)  
  444. {  
  445.     uint8_t i;  
  446.     uint16_t crc = 0xffff;  // Initial value  
  447.     while(length--)  
  448.     {  
  449.         crc ^= *data++;     // crc ^= *data; data++;  
  450.         for (i = 0; i < 8; ++i)  
  451.         {  
  452.             if (crc & 1)  
  453.                 crc = (crc >> 1) ^ 0x8408;    // 0x8408 = reverse 0x1021  
  454.             else  
  455.                 crc = (crc >> 1);  
  456.         }  
  457.     }  
  458.     return ~crc;            // crc^Xorout  
  459. }  
  460.   
  461. /****************************************************************************** 
  462.  * Name:    CRC-16/XMODEM       x16+x12+x5+1 
  463.  * Poly:    0x1021 
  464.  * Init:    0x0000 
  465.  * Refin:   False 
  466.  * Refout:  False 
  467.  * Xorout:  0x0000 
  468.  * Alias:   CRC-16/ZMODEM,CRC-16/ACORN 
  469.  *****************************************************************************/  
  470. uint16_t crc16_xmodem(uint8_t *data, uint_len length)  
  471. {  
  472.     uint8_t i;  
  473.     uint16_t crc = 0;       // Initial value  
  474.     while(length--)  
  475.     {  
  476.         crc ^= (uint16_t)(*data++) << 8; // crc ^= (uint16_t)(*data)<<8; data++;  
  477.         for (i = 0; i < 8; ++i)  
  478.         {  
  479.             if ( crc & 0x8000 )  
  480.                 crc = (crc << 1) ^ 0x1021;  
  481.             else  
  482.                 crc <<= 1;  
  483.         }  
  484.     }  
  485.     return crc;  
  486. }  
  487.   
  488. /****************************************************************************** 
  489.  * Name:    CRC-16/DNP          x16+x13+x12+x11+x10+x8+x6+x5+x2+1 
  490.  * Poly:    0x3D65 
  491.  * Init:    0x0000 
  492.  * Refin:   True 
  493.  * Refout:  True 
  494.  * Xorout:  0xFFFF 
  495.  * Use:     M-Bus,ect. 
  496.  *****************************************************************************/  
  497. uint16_t crc16_dnp(uint8_t *data, uint_len length)  
  498. {  
  499.     uint8_t i;  
  500.     uint16_t crc = 0;       // Initial value  
  501.     while(length--)  
  502.     {  
  503.         crc ^= *data++;     // crc ^= *data; data++;  
  504.         for (i = 0; i < 8; ++i)  
  505.         {  
  506.             if (crc & 1)  
  507.                 crc = (crc >> 1) ^ 0xA6BC;    // 0xA6BC = reverse 0x3D65  
  508.             else  
  509.                 crc = (crc >> 1);  
  510.         }  
  511.     }  
  512.     return ~crc;            // crc^Xorout  
  513. }  
  514.   
  515. /****************************************************************************** 
  516.  * Name:    CRC-32  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 
  517.  * Poly:    0x4C11DB7 
  518.  * Init:    0xFFFFFFF 
  519.  * Refin:   True 
  520.  * Refout:  True 
  521.  * Xorout:  0xFFFFFFF 
  522.  * Alias:   CRC_32/ADCCP 
  523.  * Use:     WinRAR,ect. 
  524.  *****************************************************************************/  
  525. uint32_t crc32(uint8_t *data, uint_len length)  
  526. {  
  527.     uint8_t i;  
  528.     uint32_t crc = 0xffffffff;  // Initial value  
  529.     while(length--)  
  530.     {  
  531.         crc ^= *data++;         // crc ^= *data; data++;  
  532.         for (i = 0; i < 8; ++i)  
  533.         {  
  534.             if (crc & 1)  
  535.                 crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7  
  536.             else  
  537.                 crc = (crc >> 1);  
  538.         }  
  539.     }  
  540.     return ~crc;  
  541. }  
  542.   
  543. /****************************************************************************** 
  544.  * Name:    CRC-32/MPEG-2  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 
  545.  * Poly:    0x4C11DB7 
  546.  * Init:    0xFFFFFFF 
  547.  * Refin:   False 
  548.  * Refout:  False 
  549.  * Xorout:  0x0000000 
  550.  * Note: 
  551.  *****************************************************************************/  
  552. uint32_t crc32_mpeg_2(uint8_t *data, uint_len length)  
  553. {  
  554.     uint8_t i;  
  555.     uint32_t crc = 0xffffffff;  // Initial value  
  556.     while(length--)  
  557.     {  
  558.         crc ^= (uint32_t)(*data++) << 24;// crc ^=(uint32_t)(*data)<<24; data++;  
  559.         for (i = 0; i < 8; ++i)  
  560.         {  
  561.             if ( crc & 0x80000000 )  
  562.                 crc = (crc << 1) ^ 0x04C11DB7;  
  563.             else  
  564.                 crc <<= 1;  
  565.         }  
  566.     }  
  567.     return crc;  
  568. }  


使用方法:
首先,根据输入数据长度定义合适的uint_len类型,
因为是逐位运算,所以不推荐用在实时性较高的的情况下,而且数据也不宜太长.
大多数嵌入式开发过程中需要校验的寄存器数据也不会太多.
这里使用:
  1. typedef uint16_t uint_len;  


  1. //定义一组测试数据:  
  2. uint8_t serno[] = { 0x91, 0xA3, 0xB5, 0xC7, 0x8D, 0xEB, 0x2D, 0x4E };  
  3. //输出测试数据的crc32校验码  
  4. printf("%x\n",crc32(serno, sizeof(serno)));  
  5. //输出测试数据的crc8校验码  
  6. printf("%x\n",crc8(serno, sizeof(serno)));  
  7. //....其它的不写了  



有几个crc函数(注意!并是不所有的)可以把校验码直接放在数据流后面一同输入,如果返回值为0,则校验通过
比如上面的serno的crc8校验码是 0X23

uint8_t serno2[] = { 0x91, 0xA3, 0xB5, 0xC7, 0x8D, 0xEB, 0x2D, 0x4E, 0x23 };
则执行printf("%x\n",crc8(serno2, sizeof(serno2)));
得到的输出即为0.
有的函数不为0的原因是最后一步进行了异或操作(return crc^Xorout)

其实crc校验都是一个套路,在写crc8的时候,写着写着就把所有的都写出来了.
crc64其实根据crc32也能很简单的写出来,用的不多,就不写了.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多