iOS CRC 校驗(yàn)

CRC校驗(yàn),全名叫做循環(huán)冗余校驗(yàn)碼,是數(shù)據(jù)通訊中最常采用的校驗(yàn)方式。
為了學(xué)習(xí)這個(gè)CRC,在網(wǎng)上找了好多資料,下面這篇文章是最清晰的,整體搬運(yùn)過來:(http://blog.163.com/du_minchao@126/blog/static/107495394201075114028606/

一、基本原理
CRC檢驗(yàn)原理實(shí)際上就是在一個(gè)p位二進(jìn)制數(shù)據(jù)序列之后附加一個(gè)r位二進(jìn)制檢驗(yàn)碼(序列),從而構(gòu)成一個(gè)總長(zhǎng)為n=p+r位的二進(jìn)制序列;附加在數(shù)據(jù)序列之后的這個(gè)檢驗(yàn)碼與數(shù)據(jù)序列的內(nèi)容之間存在著某種特定的關(guān)系。如果因干擾等原因使數(shù)據(jù)序列中的某一位或某些位發(fā)生錯(cuò)誤,這種特定關(guān)系就會(huì)被破壞。因此,通過檢查這一關(guān)系,就可以實(shí)現(xiàn)對(duì)數(shù)據(jù)正確性的檢驗(yàn)。
二、幾個(gè)基本概念

1、幀檢驗(yàn)序列FCS(Frame Check Sequence):為了進(jìn)行差錯(cuò)檢驗(yàn)而添加的冗余碼。

2、多項(xiàng)式模2運(yùn)行:實(shí)際上是按位異或(Exclusive
OR)運(yùn)算,即相同為0,相異為1,也就是不考慮進(jìn)位、借位的二進(jìn)制加減運(yùn)算。如:10011011 + 11001010 = 01010001。

3、生成多項(xiàng)式(generator
polynomial):當(dāng)進(jìn)行CRC檢驗(yàn)時(shí),發(fā)送方與接收方需要事先約定一個(gè)除數(shù),即生成多項(xiàng)式,一般記作G(x)。生成多項(xiàng)式的最高位與最低位必須是1。常用的CRC碼的生成多項(xiàng)式有:

CRC8=X8+X5+X4+1

CRC-CCITT=X16+X12+X5+1

CRC16=X16+X15+X5+1

CRC12=X12+X11+X3+X2+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

每一個(gè)生成多項(xiàng)式都可以與一個(gè)代碼相對(duì)應(yīng),如CRC8對(duì)應(yīng)代碼:100110001。

三、CRC檢驗(yàn)碼的計(jì)算

設(shè)信息字段為K位,校驗(yàn)字段為R位,則碼字長(zhǎng)度為N(N=K+R)。設(shè)雙方事先約定了一個(gè)R次多項(xiàng)式g(x),則CRC碼:

V(x)=A(x)g(x)=xRm(x)+r(x)

其中: m(x)為K次信息多項(xiàng)式, r(x)為R-1次校驗(yàn)多項(xiàng)式。

這里r(x)對(duì)應(yīng)的代碼即為冗余碼,加在原信息字段后即形成CRC碼。

r(x)的計(jì)算方法為:在K位信息字段的后面添加R個(gè)0,再除以g(x)對(duì)應(yīng)的代碼序列,得到的余數(shù)即為r(x)對(duì)應(yīng)的代碼(應(yīng)為R-1位;若不足,而在高位補(bǔ)0)。

計(jì)算示例

設(shè)需要發(fā)送的信息為M = 1010001101,產(chǎn)生多項(xiàng)式對(duì)應(yīng)的代碼為P =
110101,R=5。在M后加5個(gè)0,然后對(duì)P做模2除法運(yùn)算,得余數(shù)r(x)對(duì)應(yīng)的代碼:01110。故實(shí)際需要發(fā)送的數(shù)據(jù)是101000110101110。

這里寫圖片描述

四、錯(cuò)誤檢測(cè)
當(dāng)接收方收到數(shù)據(jù)后,用收到的數(shù)據(jù)對(duì)P(事先約定的)進(jìn)行模2除法,若余數(shù)為0,則認(rèn)為數(shù)據(jù)傳輸無差錯(cuò);若余數(shù)不為0,則認(rèn)為數(shù)據(jù)傳輸出現(xiàn)了錯(cuò)誤,由于不知道錯(cuò)誤發(fā)生在什么地方,因而不能進(jìn)行自動(dòng)糾正,一般的做法是丟棄接收的數(shù)據(jù)。
五、幾點(diǎn)說明:

1、CRC是一種常用的檢錯(cuò)碼,并不能用于自動(dòng)糾錯(cuò)。

2、只要經(jīng)過嚴(yán)格的挑選,并使用位數(shù)足夠多的除數(shù) P,那么出現(xiàn)檢測(cè)不到的差錯(cuò)的概率就很小很小。

3、僅用循環(huán)冗余檢驗(yàn) CRC 差錯(cuò)檢測(cè)技術(shù)只能做到無差錯(cuò)接受(只是非常近似的認(rèn)為是無差錯(cuò)的),并不能保證可靠傳輸。

以上是在網(wǎng)上看到的資料,而我們的項(xiàng)目中的需求是:采用16位的CRC校驗(yàn)碼,并采用CRC-CCITT多項(xiàng)式X16+X12+X5 +1。也就是在上文中沒有提到的 CRC-CCITT ,
CRC在線校驗(yàn)地址:https://www.lammertbies.nl/comm/info/crc-calculation.html
具體的代碼如下:

#import <Foundation/Foundation.h>

@interface NSData (CRC16)

//Nsdata  CRC 校驗(yàn) ,返回data
-(NSData*)crc16 ;

//Nsdata 轉(zhuǎn)化成 hex字符串
- (NSString *)hexadecimalString;

@end

#import "NSData+CRC16.h"

@implementation NSData (CRC16)


- (NSData*)crc16 {
    const uint8_t *byte = (const uint8_t *)self.bytes;
    uint16_t length = (uint16_t)self.length;
    uint16_t res =  gen_crc16(byte, length);
    
    NSData *val = [NSData dataWithBytes:&res length:sizeof(res)];
    
    return val;
}

#define PLOY 0X1021

uint16_t gen_crc16(const uint8_t *data, uint16_t size) {
    uint16_t crc = 0;
    uint8_t i;
    for (; size > 0; size--) {
        crc = crc ^ (*data++ <<8);
        for (i = 0; i < 8; i++) {
            if (crc & 0X8000) {
                crc = (crc << 1) ^ PLOY;
            }else {
                crc <<= 1;
            }
        }
        crc &= 0XFFFF;
    }
    return crc;
}


- (NSString *)hexadecimalString
{
    const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
    
    if (!dataBuffer)
    {
        return [NSString string];
    }
    
    NSUInteger          dataLength  = [self length];
    NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
    
    for (int i = 0; i < dataLength; ++i)
    {
        [hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
    }
    
    return [NSString stringWithString:hexString];
}


@end

地址:https://github.com/AmdyTeng/iOS-CRC

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容