电竞比分网-中国电竞赛事及体育赛事平台

分享

CRC算法

 wfsy1983 2011-01-01
CRC32算法(C++轉(zhuǎn)JavaScript) 收藏
這段時(shí)間我在研究一下HTML文件傳輸?shù)膯栴},但我研究的東西在發(fā)送文件過程中沒有加入校驗(yàn)碼,很多人都知道,網(wǎng)絡(luò)傳輸會(huì)存在數(shù)據(jù)丟失,錯(cuò)誤等問題,所以要自行加入校驗(yàn)碼。
在網(wǎng)上看了一些校驗(yàn)算法,發(fā)覺CRC16和CRC32相對(duì)比較簡(jiǎn)單(因?yàn)槲业奈募邮斩耸乔度胧较到y(tǒng),所以不能太復(fù)雜,以免浪費(fèi)資源),因此在網(wǎng)上找了一個(gè)C++的CRC32的算法,具體如下:
view plaincopy to clipboardprint?
unsigned int GetCrc32(char* InStr,unsigned int len){     
    //生成Crc32的查詢表  
    unsigned int Crc32Table[256];   
    int i,j;     
    unsigned int Crc;     
    for (i = 0; i < 256; i++)  
    {     
        Crc = i;     
        for (j = 0; j < 8; j++)  
        {     
            if (Crc & 1)     
                Crc = (Crc >> 1) ^ 0xEDB88320;          
            else    
                Crc >>= 1;   
        }     
        Crc32Table[i] = Crc;     
    }     
    //開始計(jì)算CRC32校驗(yàn)值  
    Crc=0xffffffff;     
    for(int i=0; i<len; i++){    
        Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]];     
    }  
      
    Crc ^= 0xFFFFFFFF;  
    return Crc;     
}    
unsigned int GetCrc32(char* InStr,unsigned int len){  
 //生成Crc32的查詢表
 unsigned int Crc32Table[256];
 int i,j;  
 unsigned int Crc;  
 for (i = 0; i < 256; i++)
 {  
  Crc = i;  
  for (j = 0; j < 8; j++)
  {  
   if (Crc & 1)  
    Crc = (Crc >> 1) ^ 0xEDB88320;     
   else 
    Crc >>= 1;
  }  
  Crc32Table[i] = Crc;  
 }  
 //開始計(jì)算CRC32校驗(yàn)值
 Crc=0xffffffff;  
 for(int i=0; i<len; i++){ 
  Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]];  
 }
 
 Crc ^= 0xFFFFFFFF;
 return Crc;  
}    上面的代碼來網(wǎng)絡(luò),本人經(jīng)過測(cè)試,在VC++中可以正常使用,而且結(jié)果也是正常的。
因?yàn)槲沂怯门cHTML,所以我想利用JS算出校驗(yàn)碼后,再發(fā)送。但由于我不太了解JS所以,只有在網(wǎng)上找找例子。因此,我在網(wǎng)上找了一段JS代碼
view plaincopy to clipboardprint?
function makeCrc32Table() {  
    if (typeof(window.crc32Table) != "undefined") return;  
    window.crc32Table = new Array(256);  
    for (var i = 0; i < 256; i++) {  
        var k = i;  
        for (var j = 0; j < 8; j++)  
            if (k & 1)  
                k = (k >> 1) ^ 0xedb88320;  
            else k >>= 1;  
        crc32Table[i] = k;  
    }  
}  
function crc32(str) {  
    makeCrc32Table();  
    if (typeof str != "string") str = "" + str;  
    var crc = 0xffffffff;  
    for (var i = 0; i < str.length; i++) {  
        var code = str.charCodeAt(i);  
        if (code > 0xff) {  
            crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code & 0xff)];  
            crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code >> 8)];  
        } else crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ code];  
    }  
    return crc ^ 0xffffffff;  

function makeCrc32Table() {
    if (typeof(window.crc32Table) != "undefined") return;
    window.crc32Table = new Array(256);
    for (var i = 0; i < 256; i++) {
        var k = i;
        for (var j = 0; j < 8; j++)
            if (k & 1)
                k = (k >> 1) ^ 0xedb88320;
            else k >>= 1;
        crc32Table[i] = k;
    }
}
function crc32(str) {
    makeCrc32Table();
    if (typeof str != "string") str = "" + str;
    var crc = 0xffffffff;
    for (var i = 0; i < str.length; i++) {
        var code = str.charCodeAt(i);
        if (code > 0xff) {
            crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code & 0xff)];
            crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code >> 8)];
        } else crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ code];
    }
    return crc ^ 0xffffffff;
}

這段代碼也是來自網(wǎng)絡(luò)的,我也研究過,算法上是一模一樣,而且一些操作符名稱上是一樣的,>>這是移位,^這是位異或,&這是位與。
經(jīng)過驗(yàn)證,發(fā)現(xiàn)了一些JS與C++運(yùn)算符的上差別:
1、>>這個(gè)是右位移,但是 它移動(dòng)后并不像C++中的>>在前面補(bǔ)零,而是在前補(bǔ)1(可能是最高位為1就補(bǔ)1,為零就補(bǔ)零),所以運(yùn)算出來的結(jié)果完全不相同。
2、在JS中,字符與上一個(gè)16進(jìn)制數(shù),結(jié)果是一個(gè)0,即‘a’&0xff 等于0,JS不同C++,C++中字符與上一個(gè)16進(jìn)制數(shù),它會(huì)自動(dòng)轉(zhuǎn)成16進(jìn)行數(shù)再進(jìn)行運(yùn)算,但在JS中與上的值就明顯不正確。
下面是我經(jīng)過修改的結(jié)果,而且通過了我的驗(yàn)證
view plaincopy to clipboardprint?
function GetCrc32(Instr)  
{  
    if(typeof(window.Crc32Table)!="undefined")return;  
    window.Crc32Table=new Array(256);  
    var i,j;  
    var Crc;  
    for(i=0; i<256; i++)  
    {  
        Crc=i;  
        for(j=0; j<8; j++)  
        {  
            if(Crc & 1)  
                Crc=((Crc >> 1)& 0x7FFFFFFF) ^ 0xEDB88320;  
            else 
                Crc=((Crc >> 1)& 0x7FFFFFFF);  
        }  
        Crc32Table[i]=Crc;  
    }  
    if (typeof Instr != "string") Instr = "" + Instr;  
    Crc=0xFFFFFFFF;  
    for(i=0; i<Instr.length; i++)  
        Crc=((Crc >> 8)&0x00FFFFFF) ^ Crc32Table[(Crc & 0xFF)^ Instr.charCodeAt(i)];  
    Crc ^=0xFFFFFFFF;  
    return Crc;  

function GetCrc32(Instr)
{
 if(typeof(window.Crc32Table)!="undefined")return;
 window.Crc32Table=new Array(256);
 var i,j;
 var Crc;
 for(i=0; i<256; i++)
 {
  Crc=i;
  for(j=0; j<8; j++)
  {
   if(Crc & 1)
    Crc=((Crc >> 1)& 0x7FFFFFFF) ^ 0xEDB88320;
   else
    Crc=((Crc >> 1)& 0x7FFFFFFF);
  }
  Crc32Table[i]=Crc;
 }
 if (typeof Instr != "string") Instr = "" + Instr;
 Crc=0xFFFFFFFF;
 for(i=0; i<Instr.length; i++)
  Crc=((Crc >> 8)&0x00FFFFFF) ^ Crc32Table[(Crc & 0xFF)^ Instr.charCodeAt(i)];
 Crc ^=0xFFFFFFFF;
 return Crc;
} 修改成上面的函數(shù)后,輸出結(jié)果是一個(gè)10進(jìn)制數(shù),可能經(jīng)過轉(zhuǎn)換后,以16進(jìn)制顯示,這里我就不再說明了。
 
本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/bakasen/archive/2010/11/29/6043797.aspx

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多