1. 程式人生 > >CRC 32 校驗

CRC 32 校驗

CRC即迴圈冗餘校驗碼(Cyclic Redundancy Check[1] )。它是一類重要的線性分組碼,編碼和解碼方法簡單,檢錯和糾錯能力強,在通訊領域廣泛地用於實現差錯控制。

引數模型 
這個很重要,計算CRC值時,不僅僅是生成項POLY會影響到CRC值,還有很多引數會影響到最終的CRC值! 我也是查了很久才知道,暈死,在網上找了好多演算法,都不是我要的結果(和另一端校驗值相等的結果,另一端是個糊塗人,也不知道引數模型,不知道從哪找的例子,copy出來就用,可惜是fpga語言,上位機不能用,可苦了我了)

CRC計算,需要有CRC引數模型,比如CRC32的引數模型是: 
Width : 32 
Poly : 04C11DB7 
RefIn : True 
RefOut : True 
XorOut : FFFFFFFF

在這裡記錄一下crc 32的生成程式碼。

  • CRC-32的預置碼錶

    計算時要選取一個多項式作為除數,一般CRC-32選取如下三個多項式值中的一個 
    Polynomial representations

    1. Normal :0x04C11DB7
    2. Reversed :0xEDB88320
    3. Reversed reciprocal :0x82608EDB

在實際資料通訊時,資訊位元組先傳送或先接收低位位元組,這時候使用翻轉反轉多項(這樣避免翻轉資料,增加運算量)

static
uint CRC32_Tbl[256]; //用來儲存CRC32碼錶 void GenCrc32Tbl() { uint CRC; for(int i=0; i<256; i++) { CRC=i; //這個迴圈實際上就是用"計演算法"來求取CRC的校驗碼 for(int j=0; j<8; j++){ if(CRC&1)//最高位為1,將它與poly做XOR運算 CRC=(CRC>>1)^0xEDB88320;//0xEDB88320是選的CRC-32多項表示式的值
else //否則我們只是將左移一位 翻轉多項式是右移一位 CRC>>=1; } CRC32_Tbl[i]=CRC; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • CRC 32 
    餘數初始值(Initial value):0xFFFFFFFF 
    結果異或值 (Final XOR value):0xFFFFFFFF
uint Get_CRC32(const unsigned  char *buf, int size)
{
    uint i, CRC;

    CRC = 0xFFFFFFFF;//#define INIT  0xFFFFFFFF  // 餘數初始值   Initial value
    for (i = 0; i < size; i++)
        CRC = CRC32_Tbl[(CRC ^ buf[i]) & 0xff] ^ (CRC >> 8);
    return CRC^0xFFFFFFFF;//#define XOROT 0xFFFFFFFF // 結果異或值  Final XOR value
}
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我使用的是另一種, MPEG-2的引數模型,這裡先不列出來程式碼了。其實只是涉及到了位的反轉



CRC即迴圈冗餘校驗碼(Cyclic Redundancy Check[1] )。它是一類重要的線性分組碼,編碼和解碼方法簡單,檢錯和糾錯能力強,在通訊領域廣泛地用於實現差錯控制。

引數模型 
這個很重要,計算CRC值時,不僅僅是生成項POLY會影響到CRC值,還有很多引數會影響到最終的CRC值! 我也是查了很久才知道,暈死,在網上找了好多演算法,都不是我要的結果(和另一端校驗值相等的結果,另一端是個糊塗人,也不知道引數模型,不知道從哪找的例子,copy出來就用,可惜是fpga語言,上位機不能用,可苦了我了)

CRC計算,需要有CRC引數模型,比如CRC32的引數模型是: 
Width : 32 
Poly : 04C11DB7 
RefIn : True 
RefOut : True 
XorOut : FFFFFFFF

在這裡記錄一下crc 32的生成程式碼。

  • CRC-32的預置碼錶

    計算時要選取一個多項式作為除數,一般CRC-32選取如下三個多項式值中的一個 
    Polynomial representations

    1. Normal :0x04C11DB7
    2. Reversed :0xEDB88320
    3. Reversed reciprocal :0x82608EDB

在實際資料通訊時,資訊位元組先傳送或先接收低位位元組,這時候使用翻轉反轉多項(這樣避免翻轉資料,增加運算量)

static uint CRC32_Tbl[256];       //用來儲存CRC32碼錶

void GenCrc32Tbl()
{
    uint CRC;
    for(int i=0; i<256; i++)
    {
        CRC=i;
        //這個迴圈實際上就是用"計演算法"來求取CRC的校驗碼
        for(int j=0; j<8; j++){   
            if(CRC&1)//最高位為1,將它與poly做XOR運算
                CRC=(CRC>>1)^0xEDB88320;//0xEDB88320是選的CRC-32多項表示式的值
            else //否則我們只是將左移一位 翻轉多項式是右移一位
                CRC>>=1;
        }
        CRC32_Tbl[i]=CRC;
    }
}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • CRC 32 
    餘數初始值(Initial value):0xFFFFFFFF 
    結果異或值 (Final XOR value):0xFFFFFFFF
uint Get_CRC32(const unsigned  char *buf, int size)
{
    uint i, CRC;

    CRC = 0xFFFFFFFF;//#define INIT  0xFFFFFFFF  // 餘數初始值   Initial value
    for (i = 0; i < size; i++)
        CRC = CRC32_Tbl[(CRC ^ buf[i]) & 0xff] ^ (CRC >> 8);
    return CRC^0xFFFFFFFF;//#define XOROT 0xFFFFFFFF // 結果異或值  Final XOR value
}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我使用的是另一種, MPEG-2的引數模型,這裡先不列出來程式碼了。其實只是涉及到了位的反轉