CRC32算法(C++轉JavaScript)

這段時間我在研究一下HTML文件傳輸的問題,但我研究的東西在發送文件過程中沒有加入校驗碼,很多人都知道,網絡傳輸會存在數據丟失,錯誤等問題,所以要自行加入校驗碼。

在網上看了一些校驗算法,發覺CRC16和CRC32相對比較簡單(因爲我的文件接收端是嵌入式系統,所以不能太複雜,以免浪費資源),因此在網上找了一個C++的CRC32的算法,具體如下:

  1. unsigned int GetCrc32(char* InStr,unsigned int len){     
  2.     //生成Crc32的查詢表  
  3.     unsigned int Crc32Table[256];   
  4.     int i,j;     
  5.     unsigned int Crc;     
  6.     for (i = 0; i < 256; i++)  
  7.     {     
  8.         Crc = i;     
  9.         for (j = 0; j < 8; j++)  
  10.         {     
  11.             if (Crc & 1)     
  12.                 Crc = (Crc >> 1) ^ 0xEDB88320;          
  13.             else    
  14.                 Crc >>= 1;   
  15.         }     
  16.         Crc32Table[i] = Crc;     
  17.     }     
  18.     //開始計算CRC32校驗值  
  19.     Crc=0xffffffff;     
  20.     for(int i=0; i<len; i++){    
  21.         Crc = (Crc >> 8)^ Crc32Table[(Crc & 0xFF) ^ InStr[i]];     
  22.     }  
  23.       
  24.     Crc ^= 0xFFFFFFFF;  
  25.     return Crc;     
  26. }     
 上面的代碼來網絡,本人經過測試,在VC++中可以正常使用,而且結果也是正常的。

 

因爲我是用與HTML,所以我想利用JS算出校驗碼後,再發送。但由於我不太瞭解JS所以,只有在網上找找例子。因此,我在網上找了一段JS代碼

[javascript] view plaincopyprint?
  1. function makeCrc32Table() {  
  2.     if (typeof(window.crc32Table) != "undefined"return;  
  3.     window.crc32Table = new Array(256);  
  4.     for (var i = 0; i < 256; i++) {  
  5.         var k = i;  
  6.         for (var j = 0; j < 8; j++)  
  7.             if (k & 1)  
  8.                 k = (k >> 1) ^ 0xedb88320;  
  9.             else k >>= 1;  
  10.         crc32Table[i] = k;  
  11.     }  
  12. }  
  13. function crc32(str) {  
  14.     makeCrc32Table();  
  15.     if (typeof str != "string") str = "" + str;  
  16.     var crc = 0xffffffff;  
  17.     for (var i = 0; i < str.length; i++) {  
  18.         var code = str.charCodeAt(i);  
  19.         if (code > 0xff) {  
  20.             crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code & 0xff)];  
  21.             crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ (code >> 8)];  
  22.         } else crc = (crc >> 8) ^ crc32Table[(crc & 0xff) ^ code];  
  23.     }  
  24.     return crc ^ 0xffffffff;  
  25. }  

這段代碼也是來自網絡的,我也研究過,算法上是一模一樣,而且一些操作符名稱上是一樣的,>>這是移位,^這是位異或,&這是位與。

 

經過驗證,發現了一些JS與C++運算符的上差別:

1、>>這個是右位移,但是 它移動後並不像C++中的>>在前面補零,而是在前補1(可能是最高位爲1就補1,爲零就補零),所以運算出來的結果完全不相同。

2、在JS中,字符與上一個16進制數,結果是一個0,即‘a’&0xff 等於0,JS不同C++,C++中字符與上一個16進制數,它會自動轉成16進行數再進行運算,但在JS中與上的值就明顯不正確。

 

下面是我經過修改的結果,而且通過了我的驗證

[javascript] view plaincopyprint?
  1. function GetCrc32(Instr)  
  2. {  
  3.     if(typeof(window.Crc32Table)!="undefined")return;  
  4.     window.Crc32Table=new Array(256);  
  5.     var i,j;  
  6.     var Crc;  
  7.     for(i=0; i<256; i++)  
  8.     {  
  9.         Crc=i;  
  10.         for(j=0; j<8; j++)  
  11.         {  
  12.             if(Crc & 1)  
  13.                 Crc=((Crc >> 1)& 0x7FFFFFFF) ^ 0xEDB88320;  
  14.             else  
  15.                 Crc=((Crc >> 1)& 0x7FFFFFFF);  
  16.         }  
  17.         Crc32Table[i]=Crc;  
  18.     }  
  19.     if (typeof Instr != "string") Instr = "" + Instr;  
  20.     Crc=0xFFFFFFFF;  
  21.     for(i=0; i<Instr.length; i++)  
  22.         Crc=((Crc >> 8)&0x00FFFFFF) ^ Crc32Table[(Crc & 0xFF)^ Instr.charCodeAt(i)];  
  23.     Crc ^=0xFFFFFFFF;  
  24.     return Crc;  
  25. }  

 修改成上面的函數後,輸出結果是一個10進制數,可能經過轉換後,以16進制顯示,這裏我就不再說明了。


http://blog.csdn.net/bakasen/article/details/6043797

發佈了15 篇原創文章 · 獲贊 14 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章