麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > C > 正文

使用C語言實現(xiàn)CRC校驗的方法

2020-01-26 16:14:23
字體:
供稿:網(wǎng)友

CRC(Cyclic Redundancy Check)校驗應(yīng)用較為廣泛,以前為了處理簡單,在程序中大多數(shù)采用LRC(Longitudinal Redundancy Check)校驗,LRC校驗很好理解,編程實現(xiàn)簡單。用了一天時間研究了CRC的C語言實現(xiàn),理解和掌握了基本原理和C語言編程。結(jié)合自己的理解簡單寫下來。

1、CRC簡介

CRC檢驗的基本思想是利用線性編碼理論,在發(fā)送端根據(jù)要傳送的k位二進(jìn)制碼序列,以一定的規(guī)則產(chǎn)生一個檢驗碼r位(就是CRC碼),附在信息后面,構(gòu)成一個新的二進(jìn)制碼序列數(shù)共(k+r)位,最后發(fā)送出去。接收端根據(jù)同樣的規(guī)則校驗,以確定傳送中是否出錯。接收端有兩種處理方式:1、計算k位序列的CRC碼,與接收到的CRC比較,一致則接收正確。2、計算整個k+r位的CRC碼,若為0,則接收正確。
CRC碼有多種檢驗位數(shù),8位、16位、32位等,原理相同。16位的CRC碼產(chǎn)生的規(guī)則是先將要發(fā)送的二進(jìn)制序列數(shù)左移16位(即乘以2的16次方后),除以一個多項式,最后所得到的余數(shù)就是CRC碼。
求CRC碼所采用的是模2運算法則,即多項式除法中采用不帶借位的減法運算,運算等同于異或運算。這一點要仔細(xì)理解,是編程的基礎(chǔ)。
CRC-16: (美國二進(jìn)制同步系統(tǒng)中采用) G(X) = X16 + X15 + X2 + 1
CRC-CCITT: (由歐洲CCITT推薦) G(X) = X16 + X12 + X5 + 1
CRC-32: G(X) = X32 + X26 + X23 + X22 + X16 +X12 + X11 + X10 + X8 + X7 + X5 + X4 + X2 + X1 + 1

2、按位計算CRC

采用CRC-CCITT多項式,多項式為0x11021,C語言編程時,參與計算為0x1021,這個地方得深入思考才能體會其中的奧妙,分享一下我的思路:當(dāng)按位計算CRC時,例如計算二進(jìn)制序列為1001 1010 1010 1111時,將二進(jìn)制序列數(shù)左移16位,即為1001 1010 1010 1111 (0000 0000 0000 0000),實際上該二進(jìn)制序列可拆分為1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……
現(xiàn)在開始分析運算:
<1>對第一個二進(jìn)制分序列求余數(shù),豎式除法即為0x10000 ^ 0x11021運算,后面的0位保留;
<2>接著對第二個二進(jìn)制分序列求余數(shù),將第一步運算的余數(shù)*2后再和第二個二進(jìn)制分序列一起對0x11021求余,這一步理解應(yīng)該沒什么問題。如果該分序列為0,無需計算。
<3>對其余的二進(jìn)制序列求余與上面兩步相同。
<4>計算到最后一位時即為整個二進(jìn)制序列的余數(shù),即為CRC校驗碼。
該計算方法相當(dāng)于對每一位計算,運算過程很容易理解,所占內(nèi)存少,缺點是一位一位計算比較耗時。
下面給出C語言實現(xiàn)方法:

復(fù)制代碼 代碼如下:

unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void main( void )
{
   unsigned long temp = 0;
   unsigned int crc;
   unsigned char i;
   unsigned char *ptr = test;

   while( len-- ) {
      for(i = 0x80; i != 0; i = i >> 1) {
         temp = temp * 2;
         if((temp & 0x10000) != 0)
            temp = temp ^ 0x11021;

         if((*ptr & i) != 0)
            temp = temp ^ (0x10000 ^ 0x11021);

     }
    ptr++;
   }
   crc = temp;
   printf("0x%x ",crc);
}


上面的程序根據(jù)運算分析而來,很容易理解。為了節(jié)約內(nèi)存空間,我們對程序作進(jìn)一步的簡化。分析可知,當(dāng)二進(jìn)制序列中上一位計算的余數(shù)第15bit位為1時,即( 上一位計算的余數(shù) & 0x8000) != 0,計算本位時,上一位余數(shù) * 2后可對0x11021作求余運算,然后再加上本位計算所得余數(shù)。這個很好理解,也就是說,打個比方,把它看作簡單的除法,計算上一位時的余數(shù)乘以2后,如果比較大可以當(dāng)被除數(shù),就再去除除數(shù)求余。有一點和普通除法不同的是,因為多項式除法中采用不帶借位的減法運算,所以0x10000也可以被0x11021除,余數(shù)并非為0x10000,而是0x1021。這個自己動手算一下就知道了。余數(shù)之和也是不帶進(jìn)位的加法運算,即異或。最后還強(qiáng)調(diào)一點,因為二進(jìn)制序列是左移16位后參與運算的,所以,一直算到序列的最后一位也是可以被除的,這點大家要明白。下面給出簡化后的C語言實現(xiàn)。
復(fù)制代碼 代碼如下:

unsigned char test[16] ={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff};
unsigned char len = 16;
void main( void )
{
   unsigned int crc = 0;
   unsigned char i;
   unsigned char *ptr = test;

   while( len-- ) {
      for(i = 0x80; i != 0; i = i >> 1) {
        if((crc & 0x8000) != 0) {
           crc = crc << 1;
           crc = crc ^ 0x1021;
        }
        else {
           crc = crc << 1;
        }
        if((*ptr & i) != 0) {
          crc = crc ^ 0x1021;
        }
     }
     ptr++;
   }

   printf("0x%x ",crc);
}


上面這段程序網(wǎng)上較為常見,但 主站蜘蛛池模板: 草操视频 | 午夜网站视频 | 日韩视频在线观看免费视频 | 国产精品免费成人 | 日韩激情 | 久久91亚洲精品久久91综合 | 国产精品片一区二区三区 | 欧美激情综合在线 | 男男羞羞视频网站国产 | 国产精品一区二区三区99 | 国产激情网 | 成人在线视频播放 | 国产手机国产手机在线 | 羞羞的视频 | 久久精品一区二区三区四区五区 | 国产精品热 | 日本欧美一区二区三区在线播 | 免费黄色大片在线观看 | 日本黄色一级视频 | 草久在线观看视频 | 国产成人自拍小视频 | 成人毛片在线免费看 | 91网视频在线观看 | 激情综合视频 | 精品国产一区二区三区在线观看 | 国产免费观看a大片的网站 欧美成人一级 | 亚洲精品成人久久久 | 中文字幕综合在线观看 | 欧美日韩亚洲不卡 | 国产亚洲精品久久久久久久软件 | 黄色午夜剧场 | 日韩精品免费一区二区三区 | 日本中文视频 | 亚洲午夜1000理论片aa | 香蕉国产9| 一级做受毛片免费大片 | chinese-xvideos | 美女黄视频在线观看 | 国产毛片aaa一区二区三区视频 | 超碰在线97国产 | 欧美城网站地址 |