Java中的CRC校驗

前言

最近客戶有CRC校驗的需求,即希望Android端對字符串進行校驗,並將生成的2個字節的CRC校驗碼追加到字符串中,然後一起寫入文件。當系統聯網後,會通過寫入的字符串去向服務器請求設備序列號,服務器會根據該字符串的原始字符串(不含校驗碼)進行校驗,如果校驗出來的值跟最後兩個字節的校驗碼匹配上,則下發一個序列號,否則爲空。

概述

CRC的校驗方式多種多樣,每個客戶都有自己的校驗方式。此次客戶提供了C語言版本的校驗方式,這邊要將C語言版本的校驗轉化爲Java版本。

但由於C語言和Java的基本類型對不上,如C語言的變量類型有符號之分,而Java則統一都帶符號,並沒有所謂的無符號類型變量。若未接觸過的同學可能要費點時間去做轉化,這裏給出轉化的技巧。

C語言版本的校驗

這裏先上C語言版本的校驗,代碼如下:

unsigned short int CRC_TABLE[16]={0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7,
0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF};

 unsigned int getCRC( char *pbuffer,  unsigned int buff_len)
{
    unsigned short int mCRC;
    unsigned char mTemp;

    mCRC=0x0;
    
    while(buff_len--)
    {
        mTemp=(unsigned char)(mCRC>>0x0C);
        mCRC<<=4;
        mCRC^=CRC_TABLE[mTemp^((*pbuffer)>>0x04)];
        mTemp=(unsigned char)(mCRC>>0x0C);
        mCRC<<=4;
        mCRC^=CRC_TABLE[mTemp^((*pbuffer)&0x0F)];
        pbuffer++;
    }
    
    return (unsigned int)mCRC;
}
複製代碼

一般CRC校驗都會有一個碼錶,用於生成校驗碼。

由於C語言有有符號和無符號之分,而Java則沒有這種區分,那麼在轉化的時候,要注意符號的問題。這裏有個技巧,轉化時,C語言和Java的類型對應關係如下:

int->int
short->int
char*->String/byte[]
char->short
複製代碼

什麼意思?即C語言使用int類型的變量時,Java也使用int類型變量,C語言使用short類型變量時,Java使用int類型變量。。。

Java版本的CRC校驗

貼上Java的CRC校驗代碼,大家對照着看就明白:

private byte[] getCRC16(String data) {
    int crc = 0x0; //這裏只需用到int的低16位即可
    short tem = 0x00;
    char[] ch = data.toCharArray();
    for (char c : ch) {
        byte b = (byte)c;
        tem = (short)((crc >> 0x0c) & 0x00ff); 
        crc <<= 4;
        crc &= 0x0000ffff;   //保證高16位一直爲0
        crc ^=crc16tab[(tem ^ (b >> 0x04))&0x000000ff]; //獲取高八位CRC校驗碼
        crc &= 0x0000ffff; 
        tem = (short)((crc >> 0x0c) & 0x00ff);
        crc <<= 4;
        crc &= 0x0000ffff;
        crc ^= crc16tab[(tem ^ (b & 0x0f)) & 0x000000ff]; //獲取低八位CRC校驗碼
        crc &= 0x0000ffff;//只需低16位的CRC校驗碼
    }
    
    byte[] res = intToByteArray(crc);//將int類型轉爲byte數組 
    
    return res;
}
複製代碼

需要注意的是,在CRC校驗中,有針對16進制字節進行校驗的,有針對字符進行校驗的,比如需要校驗如下內容:

0001020304050607
複製代碼

那麼這時需要確認清楚,到底是校驗字節,還是逐個字符的進行校驗。本文則是逐個字符進行校驗。

結語

CRC校驗多見於通訊協議中,會對通訊內容進行校驗,然後將生成的校驗碼追加到通訊幀中。也有像本文這樣子的,對某個文件中的內容進行校驗,然後生成校驗碼,提高安全性。

互動

如果文章存在錯誤描述,可直接留言,一起探討!

可能感興趣的文章

Android studio使用系統源碼的AIDL接口

Android系統開機動畫的一生

Android從上電到加載Launcher,發生了啥

最後

我在微信公衆號也有寫文章,更新比較及時,有興趣者可以掃描如下二維碼,或者微信搜索【Android系統實戰開發】,關注有驚喜哦!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章