圖解crc校驗,crc8, crc16, crc32, crc24 用 c語言和python實現

1. 背景

在做通信項目的時候,經常會有遇到校驗,比如crc32校驗,crc24校驗,網上很多可以直接計算的鏈接,有crc16/crc32的,就是沒有crc24的!這就讓我很費解,之前好不容易找到一個網站可以計算crc24,今年用的時候發現居然已經關閉了!
在這裏插入圖片描述

咱 活人不能讓尿憋死,有條件要上,沒條件,創造條件也要上。
在這裏插入圖片描述
咱自己搞一個crc24的校驗的工具,每次可以直接用。

2. 原理說明

2.1 crc概述

CRC即循環冗餘校驗碼:是數據通信領域中最常用的一種查錯校驗碼,其特徵是信息字段和校驗字段的長度可以任意選定。循環冗餘檢查(CRC)是一種數據傳輸檢錯功能,對數據進行多項式計算,並將得到的結果附在幀的後面,接收設備也執行類似的算法,以保證數據傳輸的正確性和完整性。

簡單來說crc校驗過程,就是在發送端,將需要傳輸的數據後面加上一組更具某種特定規則A生成的數據,一起傳輸到接收端,然後接收端用同樣規則A來解析接收到的數據,最後判斷出是否出錯的過程。
可以如下圖的傳輸過程:
在這裏插入圖片描述這裏的規則A就是這裏要說的crc校驗。

2.2 crc計算過程

上面提到的規則A,這裏就詳細來講解下規則A。
1.選擇一組二進制比特串,就是我們說的多項式,可以是約定的多項式,也可以是自己特用的多項式, 只要發送也接收端,用同樣的多項式就行。

2.將需要傳輸的數據G,用摸2的方式與二進制比特串相除,得到餘數M。餘數M的數據位與多項式有關,如多項式crc8 = x8 + x2 + x + 1,這個多項式的二進制位數爲9位,所以生產的餘數M爲9 - 1 =8bit。同理crc16,餘數爲16bit;crc32,餘數爲32bit。

3.將餘數M加到數據G後面,生成加了crc校驗的數據F。

下面我們用實際的例子來說明上面的幾點:
假如我們用的多項式爲 crc4 = x4 + x3 + 1,那麼二進制爲11001
如果我們需要傳輸的數據爲:1101010110,用模2除法得到餘數M。
具體的計算過程如下圖:
在這裏插入圖片描述
這裏計算出來的餘數M爲1110,也就是我們需要的crc校驗碼,FCS。
到這裏已經如果已知一個多項式,就可以計算出需要crc校驗的數據的校驗碼了。

3. 實現

3.1 常用的校驗多項式

我在項目中經常用到的校驗方式有以下幾種:

  1. CRC8 x^8 + x^5 + x^4 + 1
  2. CRC16 x^16 + x^12 + x^5 + 1
  3. CRC24 x^24 + x^23 + x^6 + x^5 + x + 1
  4. CRC32 x^32+ x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1

3.2 C語言實現CRC24

如果是用c語言硬計算,會非常的耗時,這裏提供用crc table來計算。這裏咱就提供crc24的計算c代碼了。其他的crc計算式一樣的。

crc table如下:


/* CRC table for the CRC-24.
 * The poly is 0x800063 (x^24 + x^23 + x^6 + x^5 + x + 1)
 * This table for little-endian CRC computation.
 */
const uint32_t crc24_table[256] = {
	0x00000000, 0x00848401, 0x00850801, 0x00018c00, 0x00861001, 0x00029400,
	0x00031800, 0x00879c01, 0x00802001, 0x0004a400, 0x00052800, 0x0081ac01,
	0x00063000, 0x0082b401, 0x00833801, 0x0007bc00, 0x008c4001, 0x0008c400,
	0x00094800, 0x008dcc01, 0x000a5000, 0x008ed401, 0x008f5801, 0x000bdc00,
	0x000c6000, 0x0088e401, 0x00896801, 0x000dec00, 0x008a7001, 0x000ef400,
	0x000f7800, 0x008bfc01, 0x00948001, 0x00100400, 0x00118800, 0x00950c01,
	0x00129000, 0x00961401, 0x00979801, 0x00131c00, 0x0014a000, 0x00902401,
	0x0091a801, 0x00152c00, 0x0092b001, 0x00163400, 0x0017b800, 0x00933c01,
	0x0018c000, 0x009c4401, 0x009dc801, 0x00194c00, 0x009ed001, 0x001a5400,
	0x001bd800, 0x009f5c01, 0x0098e001, 0x001c6400, 0x001de800, 0x00996c01,
	0x001ef000, 0x009a7401, 0x009bf801, 0x001f7c00, 0x00a50001, 0x00218400,
	0x00200800, 0x00a48c01, 0x00231000, 0x00a79401, 0x00a61801, 0x00229c00,
	0x00252000, 0x00a1a401, 0x00a02801, 0x0024ac00, 0x00a33001, 0x0027b400,
	0x00263800, 0x00a2bc01, 0x00294000, 0x00adc401, 0x00ac4801, 0x0028cc00,
	0x00af5001, 0x002bd400, 0x002a5800, 0x00aedc01, 0x00a96001, 0x002de400,
	0x002c6800, 0x00a8ec01, 0x002f7000, 0x00abf401, 0x00aa7801, 0x002efc00,
	0x00318000, 0x00b50401, 0x00b48801, 0x00300c00, 0x00b79001, 0x00331400,
	0x00329800, 0x00b61c01, 0x00b1a001, 0x00352400, 0x0034a800, 0x00b02c01,
	0x0037b000, 0x00b33401, 0x00b2b801, 0x00363c00, 0x00bdc001, 0x00394400,
	0x0038c800, 0x00bc4c01, 0x003bd000, 0x00bf5401, 0x00bed801, 0x003a5c00,
	0x003de000, 0x00b96401, 0x00b8e801, 0x003c6c00, 0x00bbf001, 0x003f7400,
	0x003ef800, 0x00ba7c01, 0x00c60001, 0x00428400, 0x00430800, 0x00c78c01,
	0x00401000, 0x00c49401, 0x00c51801, 0x00419c00, 0x00462000, 0x00c2a401,
	0x00c32801, 0x0047ac00, 0x00c03001, 0x0044b400, 0x00453800, 0x00c1bc01,
	0x004a4000, 0x00cec401, 0x00cf4801, 0x004bcc00, 0x00cc5001, 0x0048d400,
	0x00495800, 0x00cddc01, 0x00ca6001, 0x004ee400, 0x004f6800, 0x00cbec01,
	0x004c7000, 0x00c8f401, 0x00c97801, 0x004dfc00, 0x00528000, 0x00d60401,
	0x00d78801, 0x00530c00, 0x00d49001, 0x00501400, 0x00519800, 0x00d51c01,
	0x00d2a001, 0x00562400, 0x0057a800, 0x00d32c01, 0x0054b000, 0x00d03401,
	0x00d1b801, 0x00553c00, 0x00dec001, 0x005a4400, 0x005bc800, 0x00df4c01,
	0x0058d000, 0x00dc5401, 0x00ddd801, 0x00595c00, 0x005ee000, 0x00da6401,
	0x00dbe801, 0x005f6c00, 0x00d8f001, 0x005c7400, 0x005df800, 0x00d97c01,
	0x00630000, 0x00e78401, 0x00e60801, 0x00628c00, 0x00e51001, 0x00619400,
	0x00601800, 0x00e49c01, 0x00e32001, 0x0067a400, 0x00662800, 0x00e2ac01,
	0x00653000, 0x00e1b401, 0x00e03801, 0x0064bc00, 0x00ef4001, 0x006bc400,
	0x006a4800, 0x00eecc01, 0x00695000, 0x00edd401, 0x00ec5801, 0x0068dc00,
	0x006f6000, 0x00ebe401, 0x00ea6801, 0x006eec00, 0x00e97001, 0x006df400,
	0x006c7800, 0x00e8fc01, 0x00f78001, 0x00730400, 0x00728800, 0x00f60c01,
	0x00719000, 0x00f51401, 0x00f49801, 0x00701c00, 0x0077a000, 0x00f32401,
	0x00f2a801, 0x00762c00, 0x00f1b001, 0x00753400, 0x0074b800, 0x00f03c01,
	0x007bc000, 0x00ff4401, 0x00fec801, 0x007a4c00, 0x00fdd001, 0x00795400,
	0x0078d800, 0x00fc5c01, 0x00fbe001, 0x007f6400, 0x007ee800, 0x00fa6c01,
	0x007df000, 0x00f97401, 0x00f8f801, 0x007c7c00
};

CRC24計算函數:

/* init_vect : 初始值
 * buffer : 需要計算crc的首地址
 * len : crc地址
*/
uint32_t crc24(uint32_t init_vect, uint8_t *buffer, uint32_t len)
{
	register uint32_t crc = init_vect & 0x00FFFFFF;
	while (len-- != 0) {
		crc = crc ^ *buffer++;
		crc = (crc >> 8) ^ crc24_table[crc & 0x0FF];
	}
	return (crc & 0x00FFFFFF);
}

用上面的函數就可以計算出crc24的fcs了。

3.2 python實現CRC24

#coding=utf-8
import codecs

crc24_table = [
    0x00000000, 0x00848401, 0x00850801, 0x00018c00, 0x00861001, 0x00029400,
    0x00031800, 0x00879c01, 0x00802001, 0x0004a400, 0x00052800, 0x0081ac01,
    0x00063000, 0x0082b401, 0x00833801, 0x0007bc00, 0x008c4001, 0x0008c400,
    0x00094800, 0x008dcc01, 0x000a5000, 0x008ed401, 0x008f5801, 0x000bdc00,
    0x000c6000, 0x0088e401, 0x00896801, 0x000dec00, 0x008a7001, 0x000ef400,
    0x000f7800, 0x008bfc01, 0x00948001, 0x00100400, 0x00118800, 0x00950c01,
    0x00129000, 0x00961401, 0x00979801, 0x00131c00, 0x0014a000, 0x00902401,
    0x0091a801, 0x00152c00, 0x0092b001, 0x00163400, 0x0017b800, 0x00933c01,
    0x0018c000, 0x009c4401, 0x009dc801, 0x00194c00, 0x009ed001, 0x001a5400,
    0x001bd800, 0x009f5c01, 0x0098e001, 0x001c6400, 0x001de800, 0x00996c01,
    0x001ef000, 0x009a7401, 0x009bf801, 0x001f7c00, 0x00a50001, 0x00218400,
    0x00200800, 0x00a48c01, 0x00231000, 0x00a79401, 0x00a61801, 0x00229c00,
    0x00252000, 0x00a1a401, 0x00a02801, 0x0024ac00, 0x00a33001, 0x0027b400,
    0x00263800, 0x00a2bc01, 0x00294000, 0x00adc401, 0x00ac4801, 0x0028cc00,
    0x00af5001, 0x002bd400, 0x002a5800, 0x00aedc01, 0x00a96001, 0x002de400,
    0x002c6800, 0x00a8ec01, 0x002f7000, 0x00abf401, 0x00aa7801, 0x002efc00,
    0x00318000, 0x00b50401, 0x00b48801, 0x00300c00, 0x00b79001, 0x00331400,
    0x00329800, 0x00b61c01, 0x00b1a001, 0x00352400, 0x0034a800, 0x00b02c01,
    0x0037b000, 0x00b33401, 0x00b2b801, 0x00363c00, 0x00bdc001, 0x00394400,
    0x0038c800, 0x00bc4c01, 0x003bd000, 0x00bf5401, 0x00bed801, 0x003a5c00,
    0x003de000, 0x00b96401, 0x00b8e801, 0x003c6c00, 0x00bbf001, 0x003f7400,
    0x003ef800, 0x00ba7c01, 0x00c60001, 0x00428400, 0x00430800, 0x00c78c01,
    0x00401000, 0x00c49401, 0x00c51801, 0x00419c00, 0x00462000, 0x00c2a401,
    0x00c32801, 0x0047ac00, 0x00c03001, 0x0044b400, 0x00453800, 0x00c1bc01,
    0x004a4000, 0x00cec401, 0x00cf4801, 0x004bcc00, 0x00cc5001, 0x0048d400,
    0x00495800, 0x00cddc01, 0x00ca6001, 0x004ee400, 0x004f6800, 0x00cbec01,
    0x004c7000, 0x00c8f401, 0x00c97801, 0x004dfc00, 0x00528000, 0x00d60401,
    0x00d78801, 0x00530c00, 0x00d49001, 0x00501400, 0x00519800, 0x00d51c01,
    0x00d2a001, 0x00562400, 0x0057a800, 0x00d32c01, 0x0054b000, 0x00d03401,
    0x00d1b801, 0x00553c00, 0x00dec001, 0x005a4400, 0x005bc800, 0x00df4c01,
    0x0058d000, 0x00dc5401, 0x00ddd801, 0x00595c00, 0x005ee000, 0x00da6401,
    0x00dbe801, 0x005f6c00, 0x00d8f001, 0x005c7400, 0x005df800, 0x00d97c01,
    0x00630000, 0x00e78401, 0x00e60801, 0x00628c00, 0x00e51001, 0x00619400,
    0x00601800, 0x00e49c01, 0x00e32001, 0x0067a400, 0x00662800, 0x00e2ac01,
    0x00653000, 0x00e1b401, 0x00e03801, 0x0064bc00, 0x00ef4001, 0x006bc400,
    0x006a4800, 0x00eecc01, 0x00695000, 0x00edd401, 0x00ec5801, 0x0068dc00,
    0x006f6000, 0x00ebe401, 0x00ea6801, 0x006eec00, 0x00e97001, 0x006df400,
    0x006c7800, 0x00e8fc01, 0x00f78001, 0x00730400, 0x00728800, 0x00f60c01,
    0x00719000, 0x00f51401, 0x00f49801, 0x00701c00, 0x0077a000, 0x00f32401,
    0x00f2a801, 0x00762c00, 0x00f1b001, 0x00753400, 0x0074b800, 0x00f03c01,
    0x007bc000, 0x00ff4401, 0x00fec801, 0x007a4c00, 0x00fdd001, 0x00795400,
    0x0078d800, 0x00fc5c01, 0x00fbe001, 0x007f6400, 0x007ee800, 0x00fa6c01,
    0x007df000, 0x00f97401, 0x00f8f801, 0x007c7c00
]

class crc_calu:
    def crc24(self, octets):
        crc = 0 & 0x00FFFFFF
        try:
            for octet in octets:
                crc = crc ^ octet
                crc = (crc >> 8) ^ crc24_table[crc & 0x0FF]
        except:
            pass
        return crc & 0x00FFFFFF

ok,這樣每次我可以用python來計算crc24啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章