crc演算法原理及c語言實現 -來自(我愛微控制器)
接收方將接收到的二進位制序列數(包括資訊碼和crc碼)除以多項式,如果餘數為0,則說明傳輸中無錯誤發生,否則說明傳輸有誤,關於其原理這裡不再多述。用軟體計算crc碼時,接收方可以將接收到的資訊碼求crc碼,比較結果和接收到的crc碼是否相同。
3 按位計算crc
對於乙個二進位制序列數可以表示為式(3-1):
(3-1)
求此二進位制序列數的crc碼時,先乘以 後(既左移16位),再除以多項式g(x),所得的餘數既是所要求的crc碼。如式(3-2)所示:
(3-2)
可以設: (3-3)
其中 為整數, 為16位二進位制餘數。將式(3-3)代入式(3-2)得:
(3-4)
再設: (3-5)
其中 為整數, 為16位二進位制餘數,將式(3-5)代入式(3-4),如上類推,最後得到:
(3-6)
根據crc的定義,很顯然,十六位二進位制數 既是我們要求的crc碼。
式(3-5)是程式設計計算crc的關鍵,它說明計算本位後的crc碼等於上一位crc碼乘以2後除以多項式,所得的餘數再加上本位值除以多項式所得的餘數。由此不難理解下面求crc碼的c語言程式。*ptr指向傳送緩衝區的首位元組,len是要傳送的總位元組數,0x1021與多項式有關。
unsigned int cal_crc(unsigned char *ptr, unsigned char len) /* 余式crc乘以2再求crc */
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的crc */
}ptr++;
}return(crc);
}按位計算crc雖然**簡單,所占用的記憶體比較少,但其最大的缺點就是一位一位地計算會占用很多的處理器處理時間,尤其在高速通訊的場合,這個缺點更是不可容忍。因此下面再介紹一種按位元組查表快速計算crc的方法。
4 按位元組計算crc
不難理解,對於乙個二進位制序列數可以按位元組表示為式(4-1),其中 為乙個位元組(共8位)。
(4-1)
求此二進位制序列數的crc碼時,先乘以 後(既左移16位),再除以多項式g(x),所得的餘數既是所要求的crc碼。如式(4-2)所示:
(4-2)
可以設: (4-3)
其中 為整數, 為16位二進位制餘數。將式(4-3)代入式(4-2)得:
(4-4)
因為:
(4-5)
其中 是 的高八位, 是 的低八位。將式(4-5)代入式(4-4),經整理後得:
(4-6)
再設: (4-7)
其中 為整數, 為16位二進位制餘數。將式(4-7)代入式(4-6),如上類推,最後得:
(4-8)
很顯然,十六位二進位制數 既是我們要求的crc碼。
式(4-7)是編寫按位元組計算crc程式的關鍵,它說明計算本位元組後的crc碼等於上一位元組余式crc碼的低8位左移8位後,再加上上一位元組crc右移8位(也既取高8位)和本位元組之和後所求得的crc碼,如果我們把8位二進位制序列數的crc全部計算出來,放如乙個表裡,採用查表法,可以大大提高計算速度。由此不難理解下面按位元組求crc碼的c語言程式。*ptr指向傳送緩衝區的首位元組,len是要傳送的總位元組數,crc余式表是按0x11021多項式求出的。
unsigned int cal_crc(unsigned char *ptr, unsigned char len) ;
crc=0;
while(len--!=0)
return(crc);
}很顯然,按位元組求crc時,由於採用了查表法,大大提高了計算速度。但對於廣泛運用的8位微處理器,**空間有限,對於要求256個crc余式表(共512位元組的記憶體)已經顯得捉襟見肘了,但crc的計算速度又不可以太慢,因此再介紹下面一種按半位元組求crc的演算法。
5 按半位元組計算crc
同樣道理,對於乙個二進位制序列數可以按位元組表示為式(5-1),其中 為半個位元組(共4位)。
(5-1)
求此二進位制序列數的crc碼時,先乘以 後(既左移16位),再除以多項式g(x),所得的餘數既是所要求的crc碼。如式(4-2)所示:
(5-2)
可以設: (5-3)
其中 為整數, 為16位二進位制餘數。將式(5-3)代入式(5-2)得:
(5-4)
因為:
(5-5)
其中 是 的高4位, 是 的低12位。將式(5-5)代入式(5-4),經整理後得:
(5-6)
再設: (5-7)
其中 為整數, 為16位二進位制餘數。將式(5-7)代入式(5-6),如上類推,最後得:
(5-8)
很顯然,十六位二進位制數 既是我們要求的crc碼。
式(5-7)是編寫按位元組計算crc程式的關鍵,它說明計算本位元組後的crc碼等於上一位元組crc碼的低12位左移4位後,再加上上一位元組余式crc右移4位(也既取高4位)和本位元組之和後所求得的crc碼,如果我們把4位二進位制序列數的crc全部計算出來,放在乙個表裡,採用查表法,每個位元組算兩次(半位元組算一次),可以在速度和記憶體空間取得均衡。由此不難理解下面按半位元組求crc碼的c語言程式。*ptr指向傳送緩衝區的首位元組,len是要傳送的總位元組數,crc余式表是按0x11021多項式求出的。
unsigned cal_crc(unsigned char *ptr, unsigned char len)
crc=0;
while(len--!=0)
return(crc);
}5 結束語
以上介紹的三種求crc的程式,按位求法速度較慢,但占用最小的記憶體空間;按位元組查表求crc的方法速度較快,但占用較大的記憶體;按半位元組查表求crc的方法是前兩者的均衡,即不會占用太多的記憶體,同時速度又不至於太慢,比較適合8位小記憶體的微控制器的應用場合。以上所給的c程式可以根據各微處理器編譯器的特點作相應的改變,比如把crc余式表放到程式儲存區內等。
K means演算法介紹及C 語言實現
k means演算法是輸入聚類個數k,以及包含 n個資料物件的資料庫,輸出滿足方差最小標準的k個聚類。基本簡介k means 演算法接受輸入量 k 然後將n個資料物件劃分為 k個聚類以便使得所獲得的聚類滿足 同一聚類中的物件相似度較高 而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值...
c語言實現CRC校驗和
下面我就將今天的demo 簡單的注釋一下 在傳送方的buffer 22 中,前二十個資料為要傳送的資料,而後兩位即buffer 20 和buffer 21 中的資料就是函式int calcrc int crc,const char buf,int len 產生的crc校驗和。如下 intmain i...
CRC16常見幾個標準的演算法及C語言實現
crc16常見的標準有以下幾種,被用在各個規範中,其演算法原理基本一致,就是在資料的輸入和輸出有所差異,下邊把這些標準的差異列出,並給出c語言的演算法實現。crc16 ccitt 多項式x16 x12 x5 1 0x1021 初始值0x0000,低位在前,高位在後,結果與0x0000異或 crc16...