1. 程式人生 > >關於CRC校驗演算法及其C程式碼實現

關於CRC校驗演算法及其C程式碼實現

以CRC16作為參考:

CRC16常見的標準有以下幾種,被用在各個規範中,其演算法原理基本一致,就是在資料的輸入和輸出有所差異,下邊把這些標準的差異列出,並給出C語言的演算法實現。

CRC16_CCITT:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在後,結果與0x0000異或

CRC16_CCITT_FALSE:多項式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在後,高位在前,結果與0x0000異或

CRC16_XMODEM:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在後,高位在前,結果與0x0000異或

CRC16_X25:多項式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在後,結果與0xFFFF異或

CRC16_MODBUS:多項式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在後,結果與0x0000異或

CRC16_IBM:多項式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在後,結果與0x0000異或

CRC16_MAXIM:多項式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在後,結果與0xFFFF異或

CRC16_USB:多項式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在後,結果與0xFFFF異或

模式

多項式

初始值

資料位序

結果處理

CRC16_CCITT

x16+x12+x5+1(0x1021)

0x0000

低位在前,高位在後

與0x0000異或

CRC16_CCITT_FALSE

x16+x12+x5+1(0x1021)

0xFFFF

低位在後,高位在前

與0x0000異或

CRC16_XMODEM

x16+x12+x5+1(0x1021)

0x0000

低位在後,高位在前

與0x0000異或

CRC16_X25

x16+x12+x5+1(0x1021)

0x0000

低位在後,高位在前

與0xFFFF異或

CRC16_ MODBUS

x16+x15+x5+1(0x8005)

0xFFFF

低位在前,高位在後

與0x0000異或

CRC16_ IBM

x16+x15+x5+1(0x8005)

0x0000

低位在前,高位在後

與0x0000異或

CRC16_ MAXIM

x16+x15+x5+1(0x8005)

0x0000

低位在前,高位在後

與0xFFFF異或

CRC16_ USB

x16+x15+x5+1(0x8005)

0xFFFF

低位在前,高位在後


CRC16的演算法原理:

1.根據CRC16的標準選擇初值CRCIn的值。

2.將資料的第一個位元組與CRCIn高8位異或。

3.判斷最高位,若該位為 0 左移一位,若為 1 左移一位再與多項式Hex碼異或。

4.重複3直至8位全部移位計算結束。

5.重複將所有輸入資料操作完成以上步驟,所得16位數即16位CRC校驗碼。

根據演算法原理與標準要求就能簡單的寫出具體程式:

  1. unsigned short CRC16_CCITT(unsigned char *puchMsg, unsigned int usDataLen)  
  2. {  
  3.   unsigned short wCRCin = 0x0000;  
  4.   unsigned short wCPoly = 0x1021;  
  5.   unsigned char wChar = 0;  
  6.   while (usDataLen--)     
  7.   {  
  8.         wChar = *(puchMsg++);  
  9.         InvertUint8(&wChar,&wChar);  
  10.         wCRCin ^= (wChar << 8);  
  11.         for(int i = 0;i < 8;i++)  
  12.         {  
  13.           if(wCRCin & 0x8000)  
  14.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  15.           else
  16.             wCRCin = wCRCin << 1;  
  17.         }  
  18.   }  
  19.   InvertUint16(&wCRCin,&wCRCin);  
  20.   return (wCRCin) ;  
  21. }  
  22. unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen)  
  23. {  
  24.   unsigned short wCRCin = 0xFFFF;  
  25.   unsigned short wCPoly = 0x1021;  
  26.   unsigned char wChar = 0;  
  27.   while (usDataLen--)     
  28.   {  
  29.         wChar = *(puchMsg++);  
  30.         wCRCin ^= (wChar << 8);  
  31.         for(int i = 0;i < 8;i++)  
  32.         {  
  33.           if(wCRCin & 0x8000)  
  34.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  35.           else
  36.             wCRCin = wCRCin << 1;  
  37.         }  
  38.   }  
  39.   return (wCRCin) ;  
  40. }  
  41. unsigned short CRC16_XMODEM(unsigned char *puchMsg, unsigned int usDataLen)  
  42. {  
  43.   unsigned short wCRCin = 0x0000;  
  44.   unsigned short wCPoly = 0x1021;  
  45.   unsigned char wChar = 0;  
  46.   while (usDataLen--)     
  47.   {  
  48.         wChar = *(puchMsg++);  
  49.         wCRCin ^= (wChar << 8);  
  50.         for(int i = 0;i < 8;i++)  
  51.         {  
  52.           if(wCRCin & 0x8000)  
  53.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  54.           else
  55.             wCRCin = wCRCin << 1;  
  56.         }  
  57.   }  
  58.   return (wCRCin) ;  
  59. }  
  60. unsigned short CRC16_X25(unsigned char *puchMsg, unsigned int usDataLen)  
  61. {  
  62.   unsigned short wCRCin = 0xFFFF;  
  63.   unsigned short wCPoly = 0x1021;  
  64.   unsigned char wChar = 0;  
  65.   while (usDataLen--)     
  66.   {  
  67.         wChar = *(puchMsg++);  
  68.         InvertUint8(&wChar,&wChar);  
  69.         wCRCin ^= (wChar << 8);  
  70.         for(int i = 0;i < 8;i++)  
  71.         {  
  72.           if(wCRCin & 0x8000)  
  73.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  74.           else
  75.             wCRCin = wCRCin << 1;  
  76.         }  
  77.   }  
  78.   InvertUint16(&wCRCin,&wCRCin);  
  79.   return (wCRCin^0xFFFF) ;  
  80. }  
  81. unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)  
  82. {  
  83.   unsigned short wCRCin = 0xFFFF;  
  84.   unsigned short wCPoly = 0x8005;  
  85.   unsigned char wChar = 0;  
  86.   while (usDataLen--)     
  87.   {  
  88.         wChar = *(puchMsg++);  
  89.         InvertUint8(&wChar,&wChar);  
  90.         wCRCin ^= (wChar << 8);  
  91.         for(int i = 0;i < 8;i++)  
  92.         {  
  93.           if(wCRCin & 0x8000)  
  94.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  95.           else
  96.             wCRCin = wCRCin << 1;  
  97.         }  
  98.   }  
  99.   InvertUint16(&wCRCin,&wCRCin);  
  100.   return (wCRCin) ;  
  101. }  
  102. unsigned short CRC16_IBM(unsigned char *puchMsg, unsigned int usDataLen)  
  103. {  
  104.   unsigned short wCRCin = 0x0000;  
  105.   unsigned short wCPoly = 0x8005;  
  106.   unsigned char wChar = 0;  
  107.   while (usDataLen--)     
  108.   {  
  109.         wChar = *(puchMsg++);  
  110.         InvertUint8(&wChar,&wChar);  
  111.         wCRCin ^= (wChar << 8);  
  112.         for(int i = 0;i < 8;i++)  
  113.         {  
  114.           if(wCRCin & 0x8000)  
  115.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  116.           else
  117.             wCRCin = wCRCin << 1;  
  118.         }  
  119.   }  
  120.   InvertUint16(&wCRCin,&wCRCin);  
  121.   return (wCRCin) ;  
  122. }  
  123. unsigned short CRC16_MAXIM(unsigned char *puchMsg, unsigned int usDataLen)  
  124. {  
  125.   unsigned short wCRCin = 0x0000;  
  126.   unsigned short wCPoly = 0x8005;  
  127.   unsigned char wChar = 0;  
  128.   while (usDataLen--)     
  129.   {  
  130.         wChar = *(puchMsg++);  
  131.         InvertUint8(&wChar,&wChar);  
  132.         wCRCin ^= (wChar << 8);  
  133.         for(int i = 0;i < 8;i++)  
  134.         {  
  135.           if(wCRCin & 0x8000)  
  136.             wCRCin = (wCRCin << 1) ^ wCPoly;  
  137.           else
  138.             wCRCin = wCRCin << 1;  
  139.         }  
  140.   }  
  141.   InvertUint16(&wCRCin,&wCRCin);  
  142.   return (wCRCin^0xFFFF) ;  
  143. }  
  144. unsigned short CRC16_USB(unsigned char *puchMsg, unsigned int usDataLen)  
  145. 相關推薦

    關於CRC演算法及其C程式碼實現

    以CRC16作為參考: CRC16常見的標準有以下幾種,被用在各個規範中,其演算法原理基本一致,就是在資料的輸入和輸出有所差異,下邊把這些標準的差異列出,並給出C語言的演算法實現。 CRC16_

    [技術棧]CRC原理及C#程式碼實現CRC16、CRC32計算FCS

    1.CRC、FCS是什麼 CRC,全稱Cyclic Redundancy Check,中文名稱為迴圈冗餘校驗,是一種根據網路資料包或計算機檔案等資料產生簡短固定位數校驗碼的一種通道編碼技術,主要用來檢測或校驗資料傳輸或者儲存後可能出現的錯誤。它是利用除法及餘數的原理來作錯誤偵測的。 FCS,全稱Frame C

    各種排序演算法及其C++程式碼實現

    概念一:排序演算法是否是穩定的 給定序列{3,15,8,8,6,9} 若排序後得到{3,6,8,8,9,15}, 則該排序演算法是不穩定的,原本後面的8(加粗)現在位於前面了。 概念二: 內部排序、外部排序 內部排序是指將待排序的資料存放在記憶體中進行排序的過程。 外部排序是指待排序

    MODBUS CRC原理及C語言實現

    MODBUS通訊協議的CRC校驗原理多項式為8005的逆序A001列01的CRC校驗原理:1111111111111111                 初始化CRC寄存機0000000000000

    IP/UDP和的C程式碼實現

    序言 之前寫資料封裝程式的時候涉及到IP頭校驗和、UDP校驗和計算,在這裡回顧。 IP頭校驗和原理 IP校驗和只針對IP資料包頭部進行。在路由資料轉發的過程中如果對每一個數據包的資料都進行校驗將會是很耗時的事情,而且TCP提供了資料的差錯控制和擁塞

    CRC演算法實現 C

     標準CRC生成多項式如下表:   名稱       生成多項式             簡記式*  標準引用    CRC-4       x4+x+1                  3         ITU G.704    CRC-8       x8+x5+x

    最大堆、最小堆定義及其C++程式碼實現

    資料:https://blog.csdn.net/guoweimelon/article/details/50904346 但是它的最大堆刪除部分的程式碼有問題,詳見連結裡的評論區 定義 堆首先必須是一棵完全二叉樹 最大堆:完全二叉樹,父節點的值不小於子節點的值 最小堆:完全二叉樹,父節

    多種負載均衡演算法及其Java程式碼實現【網路上較好的轉載】

    首先給大家介紹下什麼是負載均衡(來自百科) 負載均衡 建立在現有網路結構之上,它提供了一種廉價有效透明的方法擴充套件 網路裝置和 伺服器的頻寬、增加 吞吐量、加強網路資料處理能力、提高網路的靈活性和可用性。 負載均衡,英文名稱為Load Balance,其意思就

    模擬RSA雙向驗證,並且實現DES加密以及MD5過程(python程式碼實現

    要求如下:            (1)A,B兩端各生成公鑰金鑰對(PA,SA), 金鑰對(PB,SB)。            (2)A端生成隨機數N1,用B的公鑰PB加

    PID演算法及其C語言實現

    在我們的日常生活中,總有這樣的例子,我們在走路的時候,基本上是不能閉著眼睛的,即使視力出現故障,也要有導盲犬、探路棍、盲道等措施彌補,所有這些措施其實都是提供了一個叫反饋環節的環節。我們的大腦收集到反饋資訊以後,一定會進行負反饋處理。走路的時候,眼睛看路,大腦會告訴你一個訊號:偏左了,偏右了,然後讓

    直方圖均衡化 原理及其C++程式碼實現

    演算法原理 直方圖均衡化,是對影象進行非線性拉伸,使得一定範圍內畫素值的數量的大致相同。這樣原來直方圖中的封頂部分對比度得到了增強,而兩側波谷的對比度降低,輸出的直方圖是一個較為平坦的分段直方圖。具體來講可以表現為下面這個圖: 通過這種方法可以按照需要對影象的亮度進行調整,並且,這

    連連看消除演算法C++程式碼實現

    連連看消除程式碼的實現,過程比較複雜。 #include<iostream> #include<vector> using namespace std; bool CheckRemove(int x1,int y1,int x2,int y2,int

    MD5演算法C程式碼實現及測試

    本程式主要是通過 rfc1321.txt 整理而來。這個檔案可以在下面的地址下載。 本程式在VC 2003 .NET 和 Dev C++ 4.9下編譯通過。 #include <stdio.h> typedef struct { unsigned int

    【轉】Linux下配置檔案讀取操作流程及其C程式碼實現

    轉自:http://blog.csdn.net/zhouzhaoxiong1227/article/details/45563263#comments 一、概述 Linux具有免費、可靠、安全、穩定、多平臺等特點,因此深受廣大程式設計師的歡迎。 為了體現軟體產品的靈活性,可新增配置檔案存放某些重要的

    16位CRC演算法

    CRC校驗比較常用,本例校驗演算法異或0x1021. U16 u16CRCVerify (const U8 *pu8Data, U32

    去除原始檔中的重複行的程式流程及其C程式碼實現

    一、需求描述 要求對一個包含若干行記錄且某幾條記錄相同的檔案(原始檔)實現去重操作,並將去重之後的記錄寫入到另外一個檔案(目的檔案)中。也即最後生成的檔案中沒有內容相同的兩行記錄。如果原始檔中兩條記錄之間有空行,則在目的檔案中一併將其去掉。 兩條記錄相同

    銀行卡LUHM演算法C++)

    演算法比較簡單。 1、除去校驗位後,從右至左,將卡號按位編碼,從0開始。 2、將偶數位×2,得到的結果按位相加,比如偶數為6,×2=12,則將1和2相加=3;奇數位則直接參與相加; 3、重複步驟2得到總和,該總和加上校驗位應能被10整除,否則校驗位不正確。 圖解: 設卡號

    CRCC語言實現

    ins rcc param into phoenix 兩個 The ide align 文章轉自 循環冗余校驗(CRC)算法入門引導 - Ivan 的專欄 - 博客頻道 - CSDN.NET http://blog.csdn.net/liyuanbhu/article/de

    使用C語言實現CRC的方法

    CRC(Cyclic Redundancy Check)校驗應用較為廣泛,以前為了處理簡單,在程式中大多數採用LRC(Longitudinal Redundancy Check)校驗,LRC校驗很好理解,程式設計實現簡單。用了一天時間研究了CRC的C語言實現,理解和掌握了基本原理和C語言程式設計。結合自己

    CRC的理解和C語言實現

    1、CRC是什麼 CRC檢驗的基本思想是利用線性編碼理論,在傳送端根據要傳送的k位二進位制碼序列,以一定的規則產生一個檢驗碼r位(就是CRC碼),附在資訊後面,構成一個新的二進位制碼序列數共(k+r)位,最後傳送出去。接收端根據同樣的規則校驗,以確定傳送中是否